package com.fingard.dsp.bank.directbank.abc02;


import com.fingard.FGBiz;
import com.fingard.db.JDBCHelper;
import org.apache.axis.utils.StringUtils;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.BankConfig;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.bankInterface.IElecBillTrans;
import com.fingard.dsp.bank.reqrespobj.ReqRespHeader;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.detail.RetAtsB001OperBillQryDetail;
import com.fingard.dsp.bank.reqrespobj.elecbilltrans.*;
import com.fingard.dsp.bank.reqrespobj.elecbilltrans.detail.*;
import com.fingard.dsp.bankset.BankFront;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Connection;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class ABC02ElecBillTrans extends ABC02ElecBill implements IElecBillTrans {

    public static ABC02ElecBillTrans prepare() throws Exception {
        ABC02ElecBillTrans trans = new ABC02ElecBillTrans();
        trans.setSbLog(new StringBuilder());

        HashMap<String, BankConfig> configs = new HashMap<String, BankConfig>();
        Field hashBankConfig = DirectBase.class.getDeclaredField("hashBankConfig");
        hashBankConfig.setAccessible(true);
        hashBankConfig.set(null, configs);

        trans.bankFront = new BankFront();
        trans.bankFront.org = "5000001";
        trans.bankFront.loginName = "6682100016134478";
        trans.bankFront.serverIP = "127.0.0.1";
        trans.bankFront.serverPort = "15999";
        trans.bankFront.bankCode = "ABC";

        ReqRespHeader header = new ReqRespHeader();
        header.reqSeqID = getSeqID();
        header.transSeqID = getSeqID();
        header.bankCode = "ABC";
        trans.reqHeader = header;
        BankConfig config = new BankConfig("D:\\workspace\\dsp\\config\\portfiles\\ABC02\\config.xml");
        configs.put("ABC", config);

        return trans;
    }

    public static void sendMessage() throws Exception {
        String msg = "<ap>\n" +
                "  <CCTransCode>CMLR34</CCTransCode>\n" +
                "  <ProductID>ICC</ProductID>\n" +
                "  <ChannelType>ERP</ChannelType>\n" +
                "  <CorpNo>6682100016134478</CorpNo>\n" +
                "  <OpNo>0001</OpNo>\n" +
                "  <AuthNo></AuthNo>\n" +
                "  <ReqSeqNo>112919462</ReqSeqNo>\n" +
                "  <ReqDate>20171227</ReqDate>\n" +
                "  <ReqTime>112919</ReqTime>\n" +
                "  <Sign></Sign>\n" +
                "  <Hermes>\n" +
                "    <Head>\n" +
                "      <MsgTyp>1035</MsgTyp>\n" +
                "    </Head>\n" +
                "    <IdNb>095388583299920171218094724969</IdNb>\n" +
                "    <Typ>ST00</Typ>\n" +
                "    <BusCode>1739001100000015</BusCode>\n" +
                "    <TransCode>TRE015</TransCode>\n" +
                "  </Hermes>\n" +
                "  <Cmp>\n" +
                "    <DbAccNo>402001040003008</DbAccNo>\n" +
                "    <DbProv>39</DbProv>\n" +
                "    <DbCur>01</DbCur>\n" +
                "  </Cmp>\n" +
                "</ap>";

        ABC02ElecBillTrans trans = prepare();
        trans.setSbLog(new StringBuilder());
        System.out.println(Arrays.toString(trans.sendToBank(msg)));
    }

    @Override
    public RetAtsB003BillRespSubmit D_B003_BillResp_Submit(ReqB003BillRespSubmit query) throws Exception {
        RetAtsB003BillRespSubmit Resp = new RetAtsB003BillRespSubmit(query.reqHeader);
        Resp.writeBeforeDetail();

        while (query.readRecord()) {

            XmlTextWriter writer = new XmlTextWriter();
            ABC02Header header = new ABC02Header();
            ReqB003BillRespSubmitDetail detail = query.detail;
            switch (Integer.parseInt(query.detail.respType)) {
                     /*TRE020-承兑回复
                        TRE021-收票回复
                        TRE022-背书转让回复
                        TRE029-质押回复
                        TRE030-质押解除回复
                        TRE031-保证回复
                        TRE034-同意清偿回复
                    */
                case 1: {
                    //提示承兑签收
                    header.CCTransCode = "CFRT52";
                    header.msgType = "0029";
                    header.ReqDateTime = new Date();
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);

                    //额外数据通过银行提供的接口查回
                    XmlTextReader billDataReader = CQRT07(detail.actNum, detail.actArea, detail.billCur, detail.billNo, detail.busiNo);
                    if (billDataReader == null) {
                        Resp.writeRespCode("-1");
                        Resp.writeRespInfo("从银行无法查回票据信息！");
                        Resp.writeAfter();
                        return Resp;
                    }

                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE020");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //<DuePayTyp>到期无条件支付承诺类型</DuePayTyp>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", "RC01");
                    writer.writeElementString("ResNam", billDataReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDataReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDataReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnkNam"));
                    writer.writeElementString("DuePayTyp", billDataReader.getFirstText("/ap/Hermes/AcceptInfo/DuePayTyp"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDataReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
                    writer.writeEndDocument();
                    break;
                }
                case 2: {
                    //提示收票签收
                    header.CCTransCode = "CFRT54";
                    header.msgType = "0039";


                    //额外数据通过银行提供的接口查回
                    XmlTextReader billDetailReader = CQRT09(detail.actNum, detail.actArea, detail.billCur, detail.billNo, detail.busiNo);

                    if (billDetailReader == null) {
                        Resp.writeRespCode("-1");
                        Resp.writeRespInfo("无法查回票据信息");
                        Resp.writeAfter();
                        return Resp;
                    }

                    header.ReqDateTime = new Date();
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);
                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE021");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResTyp"));
                    writer.writeElementString("ResNam", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResConBnk"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
                    writer.writeEndDocument();
                    break;
                }
                case 3: {
                    //背书转让签收
                    header.CCTransCode = "CFRT71";
                    header.msgType = "0109";

                    //额外数据通过银行提供的接口查回
                    XmlTextReader billDetailReader = CQRT11(detail.actNum, detail.actArea, detail.billCur, detail.billNo, detail.busiNo);

                    if (billDetailReader == null) {
                        Resp.writeRespCode("-1");
                        Resp.writeRespInfo("无法查回票据信息");
                        Resp.writeAfter();
                        return Resp;
                    }

                    header.ReqDateTime = new Date();
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);
                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE022");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResTyp"));
                    writer.writeElementString("ResNam", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResConBnk"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
                    writer.writeEndDocument();
                    break;
                }
                case 4:
                    //回购式贴现赎回签收
                    return null;
                case 5: {
                    //质押解除签收
                    header.CCTransCode = "CFRT63";
                    header.msgType = "0199";
                    header.ReqDateTime = new Date();
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);

                    XmlTextReader billDetailReader = CQRT20(detail.actNum, detail.actArea, detail.billCur, detail.billNo, detail.busiNo);
                    if (billDetailReader == null) {
                        Resp.writeRespCode("-1");
                        Resp.writeRespInfo("无法查回票据信息");
                        Resp.writeAfter();
                        return Resp;
                    }

                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE030");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResTyp"));
                    writer.writeElementString("ResNam", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResConBnk"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

                    writer.writeEndDocument();
                    break;
                }
                case 8: {
                    //同意清偿签收
                    header.CCTransCode = "CFRT68";
                    header.msgType = "0239";
                    header.ReqDateTime = query.reqHeader.getBusTime(new Date());
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);

                    XmlTextReader billDetailReader = CQRT24(detail.billNo, detail.busiNo, detail.actNum, detail.actArea, detail.billCur);

                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE034");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //<ResOrgCode>织机构代码</ResOrgCode>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", "RC01");
                    writer.writeElementString("ResOrgCode", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOrgCode"));
                    writer.writeElementString("ResNam", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResConBnk"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
                    writer.writeEndDocument();
                    break;
                }
                case 9: {
                    //2.7.2	质押回复申请（CFRT61）
                    header.CCTransCode = "CFRT61";
                    header.msgType = "0189";
                    header.ReqDateTime = new Date();
                    header.ReqSeqNo = query.reqHeader.transSeqID;
                    writeEleCommonHead(writer, header);

                    XmlTextReader billDetailReader = CQRT18(detail.actNum, detail.actArea, detail.billCur, detail.billNo, detail.busiNo);
                    if (billDetailReader == null) {
                        Resp.writeRespCode("-1");
                        Resp.writeRespInfo("无法查回票据信息");
                        Resp.writeAfter();
                        return Resp;
                    }

                    //<EBInfo>
                    //<IdNb>票据号码</IdNb>
                    //<BusCode>业务编号</BusCode>
                    //<TransCode>交易代码</TransCode>
                    //</EBInfo>
                    writer.writeStartElement("EBInfo");
                    writer.writeElementString("IdNb", detail.billNo);
                    writer.writeElementString("BusCode", detail.busiNo);
                    writer.writeElementString("TransCode", "TRE029");
                    writer.writeEndElement();

                    //<ResInfo>
                    //<Note>备注</Note>
                    //<ResFlag>回复标记</ResFlag>
                    //</PrxySgntr>代理回复标记</PrxySgntr>
                    //<ResTyp>类别</ResTyp>
                    //</ResNam>回复人名称</ResNam>
                    //<ResOpBnk>开户行行号</ResOpBnk>
                    //<ResConBnk>承接行行号</ResConBnk>
                    //</ResInfo>
                    writer.writeStartElement("ResInfo");
                    writer.writeElementString("Note", detail.memo);
                    writer.writeElementString("ResFlag", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("PrxySgntr", ELE_SIGN_FLAG.getNotNull(detail.respFlag));
                    writer.writeElementString("ResTyp", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResTyp"));
                    writer.writeElementString("ResOrgCode", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOrgCode"));
                    writer.writeElementString("ResNam", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResNam"));
                    writer.writeElementString("ResOpBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResOpBnk"));
                    writer.writeElementString("ResConBnk", billDetailReader.getFirstText("/ap/Hermes/ReserInfo/ResConBnk"));
                    writer.writeEndElement();

                    //<SpeInfo>
                    //<RecvBK>接收行行号</RecvBK>
                    //</SpeInfo>
                    writer.writeStartElement("SpeInfo");
                    writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/SpeInfo/RecvBK"));
                    writer.writeEndElement();
                    writer.writeEndElement();

                    //<Cmp>
                    //<DbAccNo>回复人账号</DbAccNo>
                    //<DbProv>回复人省市代码</DbProv>
                    //<DbCur>回复人货币码</DbCur>
                    //</Cmp>
                    writer.writeStartElement("Cmp");
//                    writer.writeElementString("DbAccNo", detail.actNum);
//                    writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                    writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                    writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                    writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                    String dbCur = convertCurToBank(detail.billCur);
                    writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                    writer.writeEndElement();

                    //<Amt>票据金额</Amt>
                    writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
                    writer.writeEndDocument();
                    break;
                }
                default:
                    throw new Exception("未知签收请求类型");
            }

            //发送银行
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB003BillRespSubmitDetail respDetail = new RetAtsB003BillRespSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = detail.busiNo;
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

//    public static void D_B101_BillResp_Submit_test() throws Exception {
//        ABC02ElecBillTrans trans = prepare();
//
//        Map<String, String> attributes = new HashMap();
//
//
//        XmlTextReader reader = new XmlTextReader(
//                "<ATSYH version=\"5.1.0.0\">\n" +
//                        "\t<TransReq>\n" +
//                        "\t\t<BankCode>ICBC02</BankCode>\n" +
//                        "\t\t<!--直联线路代码,参见数据字典.必填-->\n" +
//                        "\t\t<TransType>B101</TransType>\n" +
//                        "\t\t<!--指令类型,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransSeqID>%s</TransSeqID>\n", getSeqID()) +
//                        "\t\t<!--请求唯一流水号,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransTime>%s</TransTime>\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")) +
//                        "\t\t<!--请求日期时间,参见数据字典.必填-->\n" +
//                        "\t\t<TransParam>\n" +
//                        "\t\t\t<DetailRecord>\n" +
//                        String.format("\t\t\t\t<ReqSeqID>%s</ReqSeqID>\n", getSeqID()) +
//                        "\t\t\t\t<!--支付请求码-->\n" +
//                        "\t\t\t\t<BillType>2</BillType>\n" +
//                        "\t\t\t\t<!--票据类型 1-银承 2-商承-->\n" +
//                        "\t\t\t\t<IssDate>2018-02-01</IssDate>\n" +
//                        "\t\t\t\t<!--出票日-->\n" +
//                        "\t\t\t\t<DueDate>2019-01-15</DueDate>\n" +
//                        "\t\t\t\t<!--到期日-->\n" +
//                        "\t\t\t\t<BillAmt>100</BillAmt>\n" +
//                        "\t\t\t\t<!--票据金额-->\n" +
//                        "\t\t\t\t<TransFlag>1</TransFlag>\n" +
//                        "\t\t\t\t<!--转让标记 1-可再转让 2-不得转让-->\n" +
//                        "\t\t\t\t<DrawName>客户39402001040003008</DrawName>\n" +
//                        "\t\t\t\t<!--出票人名称-->\n" +
//                        "\t\t\t\t<DrawAct>402001040003008</DrawAct>\n" +
//                        "\t\t\t\t<!--出票人账号-->\n" +
//                        "\t\t\t\t<DrawCode>14453489-6</DrawCode>\n" +
//                        "\t\t\t\t<!--出票人组织机构代码-->\n" +
//                        "\t\t\t\t<DrawBnkName>中国农业银行宁波市鄞州分行</DrawBnkName>\n" +
//                        "\t\t\t\t<!--出票人开户行行名-->\n" +
//                        "\t\t\t\t<DrawBnkCode>103332040209</DrawBnkCode>\n" +
//                        "\t\t\t\t<!--出票人开户行行号-->\n" +
//                        "\t\t\t\t<CreditLv></CreditLv>\n" +
//                        "\t\t\t\t<!--信用等级-->\n" +
//                        "\t\t\t\t<GradeAgent></GradeAgent>\n" +
//                        "\t\t\t\t<!--评级机构-->\n" +
//                        "\t\t\t\t<GradeDueDate></GradeDueDate>\n" +
//                        "\t\t\t\t<!--评级到期日-->\n" +
//                        "\t\t\t\t<AccpName>客户39402001040003008</AccpName>\n" +
//                        "\t\t\t\t<!--承兑人名称-->\n" +
//                        "\t\t\t\t<AccpCode>14453489-6</AccpCode>\n" +
//                        "\t\t\t\t<!--承兑人组织机构代码-->\n" +
//                        "\t\t\t\t<AccpAct>39402001040003008</AccpAct>\n" +
//                        "\t\t\t\t<!--承兑人账号-->\n" +
//                        "\t\t\t\t<AccpBnkName>中国农业银行宁波市鄞州分行</AccpBnkName>\n" +
//                        "\t\t\t\t<!--承兑人开户行行名-->\n" +
//                        "\t\t\t\t<AccpBnkCode>103332040209</AccpBnkCode>\n" +
//                        "\t\t\t\t<!--承兑人开户行行号-->\n" +
//                        "\t\t\t\t<AccpSameBnk>1</AccpSameBnk>\n" +
//                        "\t\t\t\t<!--承兑人与出票人是否同行 1-同行 2-不同行-->\n" +
//                        "\t\t\t\t<PayeeName>客户39402001040003008</PayeeName>\n" +
//                        "\t\t\t\t<!--收款人名称-->\n" +
//                        "\t\t\t\t<PayeeAct>39402001040003008</PayeeAct>\n" +
//                        "\t\t\t\t<!--收款人账号-->\n" +
//                        "\t\t\t\t<PayeeBnkName>中国农业银行宁波市鄞州分行</PayeeBnkName>\n" +
//                        "\t\t\t\t<!--收款人开户行行名-->\n" +
//                        "\t\t\t\t<PayeeBnkCode>103332040209</PayeeBnkCode>\n" +
//                        "\t\t\t\t<!--收款人开户行行号-->\n" +
//                        "\t\t\t\t<PayeeSameBnk>1</PayeeSameBnk>\n" +
//                        "\t\t\t\t<!--收款人与出票人是否同行 1-同行 2-不同行-->\n" +
//                        "\t\t\t\t<ContractNo></ContractNo>\n" +
//                        "\t\t\t\t<!--交易合同编号-->\n" +
//                        "\t\t\t\t<InvoiceNo></InvoiceNo>\n" +
//                        "\t\t\t\t<!--发票编号-->\n" +
//                        "\t\t\t\t<Memo>试试看</Memo>\n" +
//                        "\t\t\t\t<!--备注-->\n" +
//                        "\t\t\t</DetailRecord>\n" +
//                        "\t\t</TransParam>\n" +
//                        "\t</TransReq>\n" +
//                        "</ATSYH>"
//        );
//
//
//        ReqB101BillApplySubmit submit = new ReqB101BillApplySubmit(reader, trans.reqHeader);
//
//        RetAtsB101BillApplySubmit ret = trans.D_B101_BillResp_Submit(submit);
//
//        System.out.println(trans.getSbLog());
//
//
////        System.out.println(trans.sendToBank("<ap>\n" +
////                "  <CCTransCode>CFRT51</CCTransCode>\n" +
////                "  <ProductID>ICC</ProductID>\n" +
////                "  <ChannelType>ERP</ChannelType>\n" +
////                "  <CorpNo>5000001</CorpNo>\n" +
////                "  <OpNo />\n" +
////                "  <AuthNo></AuthNo>\n" +
////                "  <ReqSeqNo>1101004493</ReqSeqNo>\n" +
////                "  <ReqDate>20171206</ReqDate>\n" +
////                "  <ReqTime>110100</ReqTime>\n" +
////                "  <Sign></Sign>\n" +
////                "  <Hermes>\n" +
////                "    <Head>\n" +
////                "      <MsgTyp>0010</MsgTyp>\n" +
////                "    </Head>\n" +
////                "    <EBInfo>\n" +
////                "      <BillTyp>AC01</BillTyp>\n" +
////                "      <IssDat>2017-12-06</IssDat>\n" +
////                "      <DueDat>2018-01-15</DueDat>\n" +
////                "      <TransFlg>EM00</TransFlg>\n" +
////                "    </EBInfo>\n" +
////                "    <BillInfo>\n" +
////                "      <DuePayTyp>CC00</DuePayTyp>\n" +
////                "      <ContNo />\n" +
////                "      <InvoiceNo />\n" +
////                "      <Object />\n" +
////                "      <BatchNo>1101008866</BatchNo>\n" +
////                "    </BillInfo>\n" +
////                "    <DrawerInfo>\n" +
////                "      <FrTyp>RC01</FrTyp>\n" +
////                "      <FrNam>客户39402001040001853</FrNam>\n" +
////                "      <FrOpBnk>103332040209</FrOpBnk>\n" +
////                "      <FrOpBnkNam>中国农业银行宁波市鄞州分行</FrOpBnkNam>\n" +
////                "      <FrPhone />\n" +
////                "      <FrAddr />\n" +
////                "    </DrawerInfo>\n" +
////                "    <AccepterInfo>\n" +
////                "      <AcepProv />\n" +
////                "      <AcepAccNo>0</AcepAccNo>\n" +
////                "      <AcepNam>中国农业银行宁波市鄞州分行</AcepNam>\n" +
////                "      <AcepOpBnk>103332040209</AcepOpBnk>\n" +
////                "      <AcepOpBnkNam>中国农业银行宁波市鄞州分行</AcepOpBnkNam>\n" +
////                "    </AccepterInfo>\n" +
////                "    <PayeeInfo>\n" +
////                "      <ToNam>客户02061601040010390</ToNam>\n" +
////                "      <ToOpBnk>103110006163</ToOpBnk>\n" +
////                "      <ToOpBnkNam>中国农业银行股份有限公司天津武清开发区支行</ToOpBnkNam>\n" +
////                "    </PayeeInfo>\n" +
////                "    <Note>试试看</Note>\n" +
////                "  </Hermes>\n" +
////                "  <Cmp>\n" +
////                "    <DbAccNo>402001040001853</DbAccNo>\n" +
////                "    <DbProv>39</DbProv>\n" +
////                "    <DbCur>01</DbCur>\n" +
////                "    <CrProv></CrProv>\n" +
////                "    <CrAccNo>02061601040010390</CrAccNo>\n" +
////                "  </Cmp>\n" +
////                "  <Amt>100.00</Amt>\n" +
////                "</ap>")[1]);
//    }

//    public static String getSeqID() {
//        Date date = new Date();
//        String hour = "";
//        String minute = "";
//        String second = "";
//        if (date.getHours() < 10) {
//            hour = "0" + date.getHours();
//        } else {
//            hour = String.valueOf(date.getHours());
//        }
//        if (date.getMinutes() < 10) {
//            minute = "0" + date.getMinutes();
//        } else {
//            minute = String.valueOf(date.getMinutes());
//        }
//
//        if (date.getSeconds() < 10) {
//            second = "0" + date.getSeconds();
//        } else {
//            second = String.valueOf(date.getSeconds());
//        }
//        String seqId = hour + minute + second;
//        return seqId + new Random().nextInt(10000);
//    }

    @Override
    public RetAtsB101BillApplySubmit D_B101_BillResp_Submit(ReqB101BillApplySubmit query) throws Exception {
        RetAtsB101BillApplySubmit result = new RetAtsB101BillApplySubmit(query.reqHeader);
        result.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();
            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT51";
            header.msgType = "0010";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB101BillApplySubmitDetail detail = query.detail;

            //<EBInfo>
            //<BillTyp>票据种类</BillTyp>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //<TransFlg>不得转让标记</TransFlg>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("BillTyp", ELE_BILL_TYPE.getNotNull(detail.billType));
            writer.writeElementString("IssDat", formatDate10(detail.issDate));
            writer.writeElementString("DueDat", formatDate10(detail.dueDate));
            writer.writeElementString("TransFlg", ELE_TRANS_FLAG.getNotNull(detail.transFlag));
            writer.writeEndElement();

            //<BillInfo>
            //<DuePayTyp>到期无条件支付承诺</DuePayTyp>  #固定为CC00
            //<ContNo>交易合同编号</ContNo>
            //<InvoiceNo>发票号码</InvoiceNo>
            //<Object>合同标的物</Object>
            //<BatchNo>批次号</BatchNo>
            //</BillInfo>
            writer.writeStartElement("BillInfo");
            writer.writeElementString("DuePayTyp", ELE_DUEPAYTYPE.getOrDefault(detail.mustPay, "CC00"));
            writer.writeElementString("ContNo", detail.contractNo);
            writer.writeElementString("InvoiceNo", detail.invoiceNo);
            writer.writeElementString("Object", "");
            writer.writeElementString("BatchNo", query.detail.reqSeqID.length() > 10 ?
                    query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10) : query.detail.reqSeqID); //相当于业务流水号，用于查询票据出票情况
            writer.writeEndElement();

            //<DrawerInfo>
            //<FrTyp>出票人类别</FrTyp>
            //<FrNam>出票人名称</FrNam>
            //<FrOpBnk>出票人开户行行号</FrOpBnk>
            //<FrOpBnkNam>出票人开户行名称</FrOpBnkNam>
            //<FrPhone>出票人电话</FrPhone>
            //<FrAddr>出票人地址</FrAddr>
            //</DrawerInfo>
            writer.writeStartElement("DrawerInfo");
            writer.writeElementString("FrTyp", "RC01");
            writer.writeElementString("FrNam", detail.drawName);
            writer.writeElementString("FrOpBnk", detail.drawBnkCode);
            writer.writeElementString("FrOpBnkNam", detail.drawBnkName);
            writer.writeElementString("FrPhone", "");
            writer.writeElementString("FrAddr", "");
            writer.writeEndElement();

            //<AccepterInfo>
            //	<AcepProv>承兑人省市代码</AcepProv>
            //<AcepAccNo>承兑人账号</AcepAccNo>
            //<AcepNam>承兑人名称</AcepNam>
            //<AcepOpBnk>承兑人开户行行号</AcepOpBnk>
            //<AcepOpBnkNam>承兑人开户行名称</AcepOpBnkNam>
            //</AccepterInfo>
            writer.writeStartElement("AccepterInfo");
            writer.writeElementString("AcepProv", "");
            writer.writeElementString("AcepAccNo", detail.accpAct);
            writer.writeElementString("AcepNam", detail.accpName);
            writer.writeElementString("AcepOpBnk", detail.accpBnkCode);
            writer.writeElementString("AcepOpBnkNam", detail.accpBnkName);
            writer.writeEndElement();

            //<PayeeInfo>
            //<ToNam>收款人名称</ToNam>
            //<ToOpBnk>收款人开户行行号</ToOpBnk>
            //<ToOpBnkNam>收款人开户行名称</ToOpBnkNam>
            //</PayeeInfo>
            writer.writeStartElement("PayeeInfo");
            writer.writeElementString("ToNam", detail.payeeName);
            writer.writeElementString("ToOpBnk", detail.payeeBnkCode);
            writer.writeElementString("ToOpBnkNam", detail.payeeBnkName);
            writer.writeEndElement();

            //<Note>备注</Note>
            writer.writeElementString("Note", detail.memo);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>出票人账号</DbAccNo>
            //<DbProv>出票人省市代码</DbProv>
            //<DbCur>出票人货币码</DbCur>
            //<CrProv>收款人省市代码</CrProv>
            //<CrAccNo>收款人账号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.drawAct);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.drawAct));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.drawAct));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.drawAct));
            writer.writeElementString("DbProv", getAbcAccProv(detail.drawAct, detail.drawActArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrProv", "");
            writer.writeElementString("CrAccNo", detail.payeeAct); //如果是农行帐号，则必须为17位
            writer.writeEndElement();

            //<Amt>票据金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB101BillApplySubmitDetail respDetail = new RetAtsB101BillApplySubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            result.writeDetail(respDetail);
        }
        result.writeAfter();
        return result;
    }

    @Override
    public RetAtsB102BillAccpSubmit D_B102_BillResp_Submit(ReqB102BillAccpSubmit query) throws Exception {
        RetAtsB102BillAccpSubmit result = new RetAtsB102BillAccpSubmit(reqHeader);
        result.writeRespCode("-1");
        result.writeRespInfo("农行不支持该操作");
        return result;
    }

    @Override
    public RetAtsB103BillRetSubmit D_B103_BillResp_Submit(ReqB103BillRetSubmit query) throws Exception {
        RetAtsB103BillRetSubmit result = new RetAtsB103BillRetSubmit(query.reqHeader);
        result.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();
            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT69";
            header.msgType = "0040";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB103BillRetSubmitDetail detail = query.detail;
            XmlTextReader billDetailReader = CQRT14(detail.actNum, detail.actArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                result.writeRespCode("-1");
                result.writeRespInfo("无法从银行查回票据明细");
                result.writeEnd();
                return result;
            }

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得装让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", billDetailReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<BillInfo>
            //<DuePayTyp>到期无条件支付承诺</DuePayTyp>
            //<ContNo>交易合同编号</ContNo>
            //<InvoiceNo>发票号码</InvoiceNo>
            //<Object>合同标的物</Object>
            //</BillInfo>
            writer.writeStartElement("BillInfo");
            writer.writeElementString("DuePayTyp", billDetailReader.getFirstText("/ap/Hermes/BillInfo/DuePayTyp"));
            writer.writeElementString("ContNo", billDetailReader.getFirstText("/ap/Hermes/BillInfo/ContNo"));
            writer.writeElementString("InvoiceNo", billDetailReader.getFirstText("/ap/Hermes/BillInfo/InvoiceNo"));
            writer.writeElementString("Object", billDetailReader.getFirstText("/ap/Hermes/BillInfo/Object"));
            writer.writeEndElement();

            //<DrawerInfo>
            //	<FrNam>出票人名称</FrNam>
            //<FrTyp>类别</FrTyp>
            //<FrOpBnk>开户行行号</FrOpBnk>
            //<FrOpBnkNam>开户行名称</FrOpBnkNam>
            //<FrPhone>电话</FrPhone>
            //<FrAddr>地址</FrAddr>
            //</DrawerInfo>
            writer.writeStartElement("DrawerInfo");
            writer.writeElementString("FrNam", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrNam"));
            writer.writeElementString("FrTyp", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrTyp"));
            writer.writeElementString("FrOpBnk", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnk"));
            writer.writeElementString("FrOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnkNam"));
            writer.writeElementString("FrPhone", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrPhone"));
            writer.writeElementString("FrAddr", billDetailReader.getFirstText("/ap/Hermes/DrawerInfo/FrAddr"));
            writer.writeEndElement();

            //<AccepterInfo>
            //<AcepAccNo>账号</AcepAccNo>
            //<AcepNam>名称</AcepNam>
            //<AcepOpBnk>开户行行号</AcepOpBnk>
            //<AcepOpBnkNam>开户行名称</AcepOpBnkNam>
            //</AccepterInfo>
            writer.writeStartElement("AccepterInfo");
            writer.writeElementString("AcepAccNo", billDetailReader.getFirstText("/ap/Hermes/AccepteInfor/AcepAccNo"));
            writer.writeElementString("AcepNam", billDetailReader.getFirstText("/ap/Hermes/AccepteInfor/AcepNam"));
            writer.writeElementString("AcepOpBnk", billDetailReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnk"));
            writer.writeElementString("AcepOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnkNam"));
            writer.writeEndElement();

            //<PayeeInfo>
            //<ToNam>名称</ToNam>
            //<ToOpBnk>开户行行号</ToOpBnk>
            //<ToOpBnkNam>开户行名称</ToOpBnkNam>
            //<ToTrdAttr>行业属性</ToTrdAttr>
            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            //</PayeeInfo>
            writer.writeStartElement("PayeeInfo");
            writer.writeElementString("ToNam", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToNam"));
            writer.writeElementString("ToOpBnk", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnk"));
            writer.writeElementString("ToOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnkNam"));
            writer.writeElementString("ToTrdAttr", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToTrdAttr"));
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", query.detail.reqSeqID.length() > 10 ?
                    query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10) : query.detail.reqSeqID);
            writer.writeEndElement();
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>出票人账号</DbAccNo>
            //<DbProv>出票人省市代码</DbProv>
            //<DbCur>出票人货币码</DbCur>
            //<CrAccNo>收款人帐号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrAccNo", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToAccNo"));
            writer.writeEndElement();

            //<Amt>金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB103BillRetSubmitDetail respDetail = new RetAtsB103BillRetSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            result.writeDetail(respDetail);
        }
        result.writeAfter();
        return result;
    }

//    public static void D_B104_BillResp_Submit_test() throws Exception {
//        ABC02ElecBillTrans trans = prepare();
//
//
//        XmlTextReader reader = new XmlTextReader(
//                "<ATSYH version=\"5.1.0.0\">\n" +
//                        "\t<TransReq>\n" +
//                        "\t\t<BankCode>ABC</BankCode>\n" +
//                        "\t\t<!--直联线路代码,参见数据字典.必填-->\n" +
//                        "\t\t<TransType>B104</TransType>\n" +
//                        "\t\t<!--指令类型,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransSeqID>%s</TransSeqID>\n", getSeqID()) +
//                        "\t\t<!--请求唯一流水号,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransTime>%s</TransTime>\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")) +
//                        "\t\t<!--请求日期时间,参见数据字典.必填-->\n" +
//                        "\t\t<TransParam>\n" +
//                        "\t\t\t<DetailRecord>\n" +
//                        String.format("\t\t\t\t<ReqSeqID>%s</ReqSeqID>\n", getSeqID()) +
//                        "\t\t\t\t<!--支付请求码-->\n" +
//                        "\t\t\t\t<ActNum>402001040003008</ActNum>\n" +
//                        "\t\t\t\t<!--银行账号-->\n" +
//                        "\t\t\t\t<BillNo>054185633299920171213142237493</BillNo>\n" +
//                        "\t\t\t\t<!--电子票据序列号-->\n" +
//                        "\t\t\t\t<Memo>好的！</Memo>\n" +
//                        "\t\t\t\t<!--备注-->\n" +
//                        "                               <BillType>2</BillType>\n" +
//                        "                               <IssDate>2018-02-01</IssDate>\n" +
//                        "                              <DueDate>2019-01-15</DueDate>\n" +
//                        "                              <BillAmt>100.00</BillAmt>\n" +
//                        "                              <TransFlag>1</TransFlag>\n" +
//                        "                              <PayeeName>客户39402001040003008</PayeeName>\n" +
//                        "                              <PayeeAct>39402001040003008</PayeeAct>\n" +
//                        "                             <PayeeBnkCode>103332040209</PayeeBnkCode>\n" +
//                        "\t\t\t</DetailRecord>\n" +
//                        "\t\t</TransParam>\n" +
//                        "\t</TransReq>\n" +
//                        "</ATSYH>"
//        );
//
//
//        ReqB104BillReceSubmit submit = new ReqB104BillReceSubmit(reader, trans.reqHeader);
//
//        try {
//            RetAtsB104BillReceSubmit ret = trans.D_B104_BillResp_Submit(submit);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        System.out.println(trans.getSbLog());
//
//
////        System.out.println(trans.sendToBank("<ap>\n" +
////                "  <CCTransCode>CFRT51</CCTransCode>\n" +
////                "  <ProductID>ICC</ProductID>\n" +
////                "  <ChannelType>ERP</ChannelType>\n" +
////                "  <CorpNo>5000001</CorpNo>\n" +
////                "  <OpNo />\n" +
////                "  <AuthNo></AuthNo>\n" +
////                "  <ReqSeqNo>1101004493</ReqSeqNo>\n" +
////                "  <ReqDate>20171206</ReqDate>\n" +
////                "  <ReqTime>110100</ReqTime>\n" +
////                "  <Sign></Sign>\n" +
////                "  <Hermes>\n" +
////                "    <Head>\n" +
////                "      <MsgTyp>0010</MsgTyp>\n" +
////                "    </Head>\n" +
////                "    <EBInfo>\n" +
////                "      <BillTyp>AC01</BillTyp>\n" +
////                "      <IssDat>2017-12-06</IssDat>\n" +
////                "      <DueDat>2018-01-15</DueDat>\n" +
////                "      <TransFlg>EM00</TransFlg>\n" +
////                "    </EBInfo>\n" +
////                "    <BillInfo>\n" +
////                "      <DuePayTyp>CC00</DuePayTyp>\n" +
////                "      <ContNo />\n" +
////                "      <InvoiceNo />\n" +
////                "      <Object />\n" +
////                "      <BatchNo>1101008866</BatchNo>\n" +
////                "    </BillInfo>\n" +
////                "    <DrawerInfo>\n" +
////                "      <FrTyp>RC01</FrTyp>\n" +
////                "      <FrNam>客户39402001040001853</FrNam>\n" +
////                "      <FrOpBnk>103332040209</FrOpBnk>\n" +
////                "      <FrOpBnkNam>中国农业银行宁波市鄞州分行</FrOpBnkNam>\n" +
////                "      <FrPhone />\n" +
////                "      <FrAddr />\n" +
////                "    </DrawerInfo>\n" +
////                "    <AccepterInfo>\n" +
////                "      <AcepProv />\n" +
////                "      <AcepAccNo>0</AcepAccNo>\n" +
////                "      <AcepNam>中国农业银行宁波市鄞州分行</AcepNam>\n" +
////                "      <AcepOpBnk>103332040209</AcepOpBnk>\n" +
////                "      <AcepOpBnkNam>中国农业银行宁波市鄞州分行</AcepOpBnkNam>\n" +
////                "    </AccepterInfo>\n" +
////                "    <PayeeInfo>\n" +
////                "      <ToNam>客户02061601040010390</ToNam>\n" +
////                "      <ToOpBnk>103110006163</ToOpBnk>\n" +
////                "      <ToOpBnkNam>中国农业银行股份有限公司天津武清开发区支行</ToOpBnkNam>\n" +
////                "    </PayeeInfo>\n" +
////                "    <Note>试试看</Note>\n" +
////                "  </Hermes>\n" +
////                "  <Cmp>\n" +
////                "    <DbAccNo>402001040001853</DbAccNo>\n" +
////                "    <DbProv>39</DbProv>\n" +
////                "    <DbCur>01</DbCur>\n" +
////                "    <CrProv></CrProv>\n" +
////                "    <CrAccNo>02061601040010390</CrAccNo>\n" +
////                "  </Cmp>\n" +
////                "  <Amt>100.00</Amt>\n" +
////                "</ap>")[1]);
//    }

    @Override
    public RetAtsB104BillReceSubmit D_B104_BillResp_Submit(ReqB104BillReceSubmit query) throws Exception {
        RetAtsB104BillReceSubmit result = new RetAtsB104BillReceSubmit(query.reqHeader);
        result.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();
            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT53";
            header.msgType = "0030";
            header.ReqDateTime = query.reqHeader.getBusTime(new Date());
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB104BillReceSubmitDetail detail = query.detail;

            XmlTextReader billDataReader = CQRT14(detail.actNum, detail.actArea, detail.billCur, detail.billNo);
            if (billDataReader == null) {
                result.writeRespCode("-1");
                result.writeRespInfo("无法从银行查回票据信息！");
                result.writeEnd();
                return result;
            }

            //<DrawerInfo>
            //<FrNam>出票人名称</FrNam>
            //<FrTyp>出票人类别</FrTyp>
            //<FrOpBnk>出票人开户行行号</FrOpBnk>
            //<FrOpBnkNam>出票人开户行名称</FrOpBnkNam>
            //<FrPhone>出票人电话</FrPhone>
            //<FrAddr>出票人地址</FrAddr>
            //</DrawerInfo>
            writer.writeStartElement("DrawerInfo");
            writer.writeElementString("FrNam", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrNam"));
            writer.writeElementString("FrTyp", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrTyp"));
            writer.writeElementString("FrOpBnk", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnk"));
            writer.writeElementString("FrOpBnkNam", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnkNam"));
            writer.writeElementString("FrPhone", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrPhone"));
            writer.writeElementString("FrAddr", billDataReader.getFirstText("/ap/Hermes/DrawerInfo/FrAddr"));
            writer.writeEndElement();

            //<PayeeInfo>
            //<ToNam>收款人名称</ToNam>
            //<ToOpBnk>收款人开户行行号</ToOpBnk>
            //<ToOpBnkNam>收款人开户行名称</ToOpBnkNam>
            //<ToTrdAttr>收款人行业属性</ToTrdAttr>
            //</PayeeInfo>
            writer.writeStartElement("PayeeInfo");
            writer.writeElementString("ToNam", billDataReader.getFirstText("/ap/Hermes/PayeeInfo/ToNam"));
            writer.writeElementString("ToOpBnk", billDataReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnk"));
            writer.writeElementString("ToOpBnkNam", billDataReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnkNam"));
            writer.writeElementString("ToTrdAttr", billDataReader.getFirstText("/ap/Hermes/PayeeInfo/ToTrdAttr"));
            writer.writeEndElement();

            //<AccepterInfo>
            //<AcepProv>承兑人省市代码</AcepProv>
            //<AcepAccNo>承兑人账号</AcepAccNo>
            //<AcepNam>承兑人名称</AcepNam>
            //<AcepOpBnk>承兑人开户行行号</AcepOpBnk>
            //<AcepOpBnkNam>承兑人开户行名称</AcepOpBnkNam>
            //</AccepterInfo>
            writer.writeStartElement("AccepterInfo");
            writer.writeElementString("AcepProv", "");
            writer.writeElementString("AcepAccNo", billDataReader.getFirstText("/ap/Hermes/AccepteInfor/AcepAccNo"));
            writer.writeElementString("AcepNam", billDataReader.getFirstText("/ap/Hermes/AccepteInfor/AcepNam"));
            writer.writeElementString("AcepOpBnk", billDataReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnk"));
            writer.writeElementString("AcepOpBnkNam", billDataReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnkNam"));
            writer.writeEndElement();


            //<BillInfo>
            //<DuePayTyp>到期无条件支付承诺</DuePayTyp>
            //<ContNo>交易合同编号</ContNo>
            //<InvoiceNo>发票号码</InvoiceNo>
            //<Object>合同标的物</Object>
            //<BatchNo>批次号</BatchNo>
            //</BillInfo>
            writer.writeStartElement("BillInfo");
            writer.writeElementString("DuePayTyp", billDataReader.getFirstText("/ap/Hermes/BillInfo/DuePayTyp"));
            writer.writeElementString("ContNo", billDataReader.getFirstText("/ap/Hermes/BillInfo/ContNo"));
            writer.writeElementString("InvoiceNo", billDataReader.getFirstText("/ap/Hermes/BillInfo/InvoiceNo"));
            writer.writeElementString("Object", billDataReader.getFirstText("/ap/Hermes/BillInfo/Object"));
            writer.writeElementString("BatchNo", query.detail.reqSeqID.length() > 10 ?
                    query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10) : query.detail.reqSeqID);
            writer.writeEndElement();

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDataReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", billDataReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"));
            writer.writeElementString("IssDat", billDataReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDataReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<Note>备注</Note>
            writer.writeElementString("Note", detail.memo);

            writer.writeEndElement();

            //<Amt>票据金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //<Cmp>
            //<DbAccNo>出票人账号</DbAccNo>
            //<DbProv>出票人省市代码</DbProv>
            //<DbCur>出票人货币码</DbCur>
            //<CrProv>收款人省市代码</CrProv>
            //<CrAccNo>收款人账号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrProv", "");
            writer.writeElementString("CrAccNo", billDataReader.getFirstText("/ap/Hermes/PayeeInfo/ToAccNo"));
            writer.writeEndElement();

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB104BillReceSubmitDetail respDetail = new RetAtsB104BillReceSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            result.writeRespCode(respDetail.respCode);
            result.writeRespInfo(respDetail.respInfo);
            result.writeDetail(respDetail);

        }

        result.writeAfter();
        return result;
    }

//    public static void D_B105_BillResp_Submit_test() throws Exception {
//        ABC02ElecBillTrans trans = prepare();
//
//
//        XmlTextReader reader = new XmlTextReader(
//                "<ATSYH version=\"5.1.0.0\"><TransReq><BankCode>ABC02</BankCode><SystemCode></SystemCode><TransType>B105</TransType><TransSeqID>1159286557</TransSeqID><TransTime>2017-12-21 11:59:28</TransTime><TransParam><DetailRecord><ReqSeqID>RN00000079</ReqSeqID><ActNum>402001040003008</ActNum><BillNo>" +
//                        "054185633299920171213142237493</BillNo><TransFlag>1</TransFlag><ReceName>客户39402001040003008</ReceName><ReceAct>39402001040003008</ReceAct><ReceBnkName>中国农业银行股份有限公司宁波鄞州分行</ReceBnkName><ReceBnkCode>103332040209</ReceBnkCode><Memo>客户</Memo><BillAmt>100</BillAmt><EndoName>客户39402001040003008</EndoName><EndoBnkCode>103332040209</EndoBnkCode><BillOpenName>客户39402001040003008</BillOpenName><BillOpenAcc>39402001040003008</BillOpenAcc><BillOpenBank>null</BillOpenBank><RecCityName>浙江省_宁波市</RecCityName><ReceSameBank>2</ReceSameBank></DetailRecord></TransParam></TransReq></ATSYH>"
//        );
//
//
//        ReqB105BillEndoSubmit submit = new ReqB105BillEndoSubmit(reader, trans.reqHeader);
//
//        RetAtsB105BillEndoSubmit ret = trans.D_B105_BillResp_Submit(submit);
//
//        System.out.println(trans.getSbLog());
//        System.out.println("返回" + ret.getRetAtsString());
//
////        System.out.println(trans.sendToBank("<ap>\n" +
////                "  <CCTransCode>CFRT51</CCTransCode>\n" +
////                "  <ProductID>ICC</ProductID>\n" +
////                "  <ChannelType>ERP</ChannelType>\n" +
////                "  <CorpNo>5000001</CorpNo>\n" +
////                "  <OpNo />\n" +
////                "  <AuthNo></AuthNo>\n" +
////                "  <ReqSeqNo>1101004493</ReqSeqNo>\n" +
////                "  <ReqDate>20171206</ReqDate>\n" +
////                "  <ReqTime>110100</ReqTime>\n" +
////                "  <Sign></Sign>\n" +
////                "  <Hermes>\n" +
////                "    <Head>\n" +
////                "      <MsgTyp>0010</MsgTyp>\n" +
////                "    </Head>\n" +
////                "    <EBInfo>\n" +
////                "      <BillTyp>AC01</BillTyp>\n" +
////                "      <IssDat>2017-12-06</IssDat>\n" +
////                "      <DueDat>2018-01-15</DueDat>\n" +
////                "      <TransFlg>EM00</TransFlg>\n" +
////                "    </EBInfo>\n" +
////                "    <BillInfo>\n" +
////                "      <DuePayTyp>CC00</DuePayTyp>\n" +
////                "      <ContNo />\n" +
////                "      <InvoiceNo />\n" +
////                "      <Object />\n" +
////                "      <BatchNo>1101008866</BatchNo>\n" +
////                "    </BillInfo>\n" +
////                "    <DrawerInfo>\n" +
////                "      <FrTyp>RC01</FrTyp>\n" +
////                "      <FrNam>客户39402001040001853</FrNam>\n" +
////                "      <FrOpBnk>103332040209</FrOpBnk>\n" +
////                "      <FrOpBnkNam>中国农业银行宁波市鄞州分行</FrOpBnkNam>\n" +
////                "      <FrPhone />\n" +
////                "      <FrAddr />\n" +
////                "    </DrawerInfo>\n" +
////                "    <AccepterInfo>\n" +
////                "      <AcepProv />\n" +
////                "      <AcepAccNo>0</AcepAccNo>\n" +
////                "      <AcepNam>中国农业银行宁波市鄞州分行</AcepNam>\n" +
////                "      <AcepOpBnk>103332040209</AcepOpBnk>\n" +
////                "      <AcepOpBnkNam>中国农业银行宁波市鄞州分行</AcepOpBnkNam>\n" +
////                "    </AccepterInfo>\n" +
////                "    <PayeeInfo>\n" +
////                "      <ToNam>客户02061601040010390</ToNam>\n" +
////                "      <ToOpBnk>103110006163</ToOpBnk>\n" +
////                "      <ToOpBnkNam>中国农业银行股份有限公司天津武清开发区支行</ToOpBnkNam>\n" +
////                "    </PayeeInfo>\n" +
////                "    <Note>试试看</Note>\n" +
////                "  </Hermes>\n" +
////                "  <Cmp>\n" +
////                "    <DbAccNo>402001040001853</DbAccNo>\n" +
////                "    <DbProv>39</DbProv>\n" +
////                "    <DbCur>01</DbCur>\n" +
////                "    <CrProv></CrProv>\n" +
////                "    <CrAccNo>02061601040010390</CrAccNo>\n" +
////                "  </Cmp>\n" +
////                "  <Amt>100.00</Amt>\n" +
////                "</ap>")[1]);
//    }

    //背书转让申请
    @Override
    public RetAtsB105BillEndoSubmit D_B105_BillResp_Submit(ReqB105BillEndoSubmit query) throws Exception {
        if (getBankConfig().getValueAsBool("isUseBillPoolTrans")) {
            //托管池的背书转让
            return billPool_CFRTA3(query);
        } else {
            //原来的电票的背书转让
            return elecBill_CFRT55(query);
        }

    }

    //托管池的背书转让
    public RetAtsB105BillEndoSubmit billPool_CFRTA3(ReqB105BillEndoSubmit p_req105) throws Exception {
        RetAtsB105BillEndoSubmit retAts = new RetAtsB105BillEndoSubmit(p_req105.reqHeader);
        retAts.writeBeforeDetail();
        try {
            while (p_req105.readRecord()) {
                //背书人票据信息
                ReqB105BillEndoSubmitDetail detail = p_req105.detail;
                XmlTextReader billDetailReader = CQRT36(detail.billNo);
                if (billDetailReader == null) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("无法从银行查回票据信息");
                    retAts.writeAfter();
                    return retAts;
                }

                //发送背书转让申请给银行
                XmlTextWriter writerXml = new XmlTextWriter();
                ABC02Header header = new ABC02Header();
                header.CCTransCode = "CFRTA3";
                header.msgType = "5100";
                header.ReqDateTime = new Date();
                header.ReqSeqNo = getReqID();
                writeBillPoolCommonHead(writerXml, header);
                writerXml.writeStartElement("EBInfo");
                writerXml.writeElementString("ClientId", billDetailReader.getFirstText("/ap/Hermes/EBInfo/ClientId"), true);//持票单位ID
                writerXml.writeElementString("IdNb", p_req105.detail.billNo);//票据号码
                writerXml.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"), true);

                writerXml.writeElementString("TransFlg", billDetailReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"), true);//不得转让标记
                writerXml.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"), true);//出票日期
                writerXml.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"), true);//到期日
                writerXml.writeEndElement();//EBInfo

                writerXml.writeStartElement("Endrsee");
                writerXml.writeElementString("EseProv", getAbcAccProv(p_req105.detail.receAct, p_req105.detail.receBnkArea), true);//省市代码
                writerXml.writeElementString("EseNam", p_req105.detail.receName, true);//被背书人名称
                writerXml.writeElementString("EseOpBnk", p_req105.detail.receBnkCode, true);//被背书人开户行行号
                writerXml.writeElementString("EseOpBnkNam", p_req105.detail.receBnkName, true);//被背书人开户行名称
                writerXml.writeEndElement();//Endrsee

                writerXml.writeStartElement("Endrsr");
                writerXml.writeElementString("EsrNam", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrNam"), true);//名称
                //CpsrTyp:RC00接入行 RC01企业 RC02人民银行 RC03被代理行 RC04被代理财务公司 RC05接入财务公司
                writerXml.writeElementString("EsrTyp", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrTyp"), true);//类别
                writerXml.writeElementString("EsrOrgCode", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrOrgCode"), true);//组织机构代码
                writerXml.writeElementString("EsrOpBnk", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrOpBnk"), true);//开户行行号
                writerXml.writeElementString("EsrOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrOpBnkNam"), true);//开户行名称
                writerXml.writeElementString("EsrConBnk", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrConBnk"), true);//承接行行号
                writerXml.writeElementString("EsrConBnkNam", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrConBnkNam"), true);//承接行名称
                writerXml.writeEndElement();//Endrsr

                writerXml.writeElementString("BatchNo", "", true);//批次号
                writerXml.writeElementString("Note", p_req105.detail.memo, true);//备注
                writerXml.writeEndElement();//Hermes

                writerXml.writeStartElement("Cmp");
                writerXml.writeElementString("CrProv", getAbcAccProv(p_req105.detail.receAct, p_req105.detail.receBnkArea), true);//省市代码
//                writerXml.writeElementString("CrProv", "", true);//省市代码
                writerXml.writeElementString("CrAccNo", getAbcAccNo(p_req105.detail.receAct), true);//被背书人账号
                writerXml.writeElementString("DbProv", getAbcAccProv(p_req105.detail.actNum, p_req105.detail.endoBnkArea), true);//省市代码
//                writerXml.writeElementString("DbProv", "", true);//省市代码
                writerXml.writeElementString("DbAccNo", getAbcAccNo(p_req105.detail.actNum), true);//背书人账号
                writerXml.writeEndElement();//Cmp

                writerXml.writeElementString("Amt", p_req105.detail.billAmt);//票据金额
                writerXml.writeEndDocument();

                String[] tmpStrRet = sendToBank(writerXml.toXmlString());

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        RetAtsB105BillEndoSubmitDetail retAteDetail = new RetAtsB105BillEndoSubmitDetail();
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        retAts.writeRespCode("0");
                        retAts.writeRespInfo(StringHelper.joinNotEmpty(";", tmpRetInfo, tmpRetRxtInfo));
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            retAteDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        retAteDetail.respCode = "0";
                        retAteDetail.respInfo = tmpRetInfo;
                        retAteDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        retAteDetail.payInfoCode = retAteDetail.transState;
                        retAts.writeDetail(retAteDetail);
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpStrRet[1]);
                }
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            WriteBankLogLn("出现异常:" + e.getMessage());
        }
        retAts.writeAfter();
        return retAts;
    }

    //原来的电票的背书转让
    public RetAtsB105BillEndoSubmit elecBill_CFRT55(ReqB105BillEndoSubmit query) throws Exception {
        RetAtsB105BillEndoSubmit Resp = new RetAtsB105BillEndoSubmit(query.reqHeader);
        Resp.writeBeforeDetail();

        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT55";
            header.msgType = "0100";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);


            ReqB105BillEndoSubmitDetail detail = query.detail;

            XmlTextReader billDetailReader = CQRT10(detail.actNum, detail.endoBnkArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法从银行查回票据信息");
                Resp.writeAfter();
                return Resp;
            }


            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", ELE_TRANS_FLAG.getNotNull(detail.transFlag));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<Endrsee>
            //<EseNam>被背书人名称</EseNam>
            //<EseOpBnk>被背书人开户行行号</EseOpBnk>
            //<EseOpBnkNam>被背书人开户行名称</EseOpBnkNam>
            //</Endrsee>
            writer.writeStartElement("Endrsee");
            writer.writeElementString("EseNam", detail.receName);
            writer.writeElementString("EseOpBnk", detail.receBnkCode);
            writer.writeElementString("EseOpBnkNam", detail.receBnkName);
            writer.writeEndElement();

            //<Endrsr>
            //<EsrNam>背书人名称</EsrNam>
            //<EsrTyp>背书人类别</EsrTyp>
            //<EsrOpBnk>背书人开户行行号</EsrOpBnk>
            //<EsrOpBnkNam>背书人开户行名称</EsrOpBnkNam>
            //<EsrConBnk>承接行行号</EsrConBnk>
            //<EsrConBnkNam>承接行名称</EsrConBnkNam>
            //</Endrsr>
            writer.writeStartElement("Endrsr");
            writer.writeElementString("EsrNam", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrNam"));
            writer.writeElementString("EsrTyp", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrTyp"));
            writer.writeElementString("EsrOpBnk", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrOpBnk"));
            writer.writeElementString("EsrOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrOpBnkNam"));
            writer.writeElementString("EsrConBnk", billDetailReader.getFirstText("/ap/Hermes/Endrsr/EsrConBnk"));
            writer.writeElementString("EsrConBnkNam", billDetailReader.getFirstText("/ap/Endrsr/EsrConBnkNam"));
            writer.writeEndElement();

            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", query.detail.reqSeqID.length() > 10 ?
                    query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10) : query.detail.reqSeqID);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>背书人账号</DbAccNo>
            //<DbProv>背书人省市代码</DbProv>
            //<DbCur>背书人货币码</DbCur>
            //<CrProv>被背书人省市代码</CrProv>
            //<CrAccNo>被背书人账号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.endoBnkArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrProv", "");
            if (query.detail.receBnkCode.startsWith("103") && !"0".equals(query.detail.receAct)) {
                writer.writeElementString("CrAccNo", getFullAct(query.detail.receAct, query.detail.receBnkArea));
            } else {
                writer.writeElementString("CrAccNo", query.detail.receAct);
            }
            writer.writeEndElement();

            //<Amt>票据金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB105BillEndoSubmitDetail respDetail = new RetAtsB105BillEndoSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    @Override
    public RetAtsB106BillDiscSubmit D_B106_BillResp_Submit(ReqB106BillDiscSubmit query) throws Exception {
        if (getBankConfig().getValueAsBool("isUseBillPoolTrans")) {
            //托管池的贴现申请
            return billPool_B106(query);
        } else {
            //原来的电票的贴现申请
            return elecBill_B106(query);
        }
    }

    //托管池的贴现申请
    public RetAtsB106BillDiscSubmit billPool_B106(ReqB106BillDiscSubmit p_req106) throws Exception {
        RetAtsB106BillDiscSubmit retAts = new RetAtsB106BillDiscSubmit(p_req106.reqHeader);
        retAts.writeBeforeDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            while (p_req106.readRecord()) {
                //1.先判断查询的账户在本地数据库是否有对应的持票人ID
                Map<String, Object> map = JDBCHelper.execQuerySingle(conn, SELECTCLIENTID, new Object[]{p_req106.detail.discName, p_req106.reqHeader.bankCode});
                if (map.size() == 0) {
                    //如果没有持票人ID 则调用CQRM15 查询全量持票人ID 更新DSP数据库
                    String returnMsg = getClientId(p_req106.reqHeader.bankCode, p_req106.detail.discName);
                    if (!StringHelper.isNullOrEmpty(returnMsg)) {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo("没有查询到该贴现账号持票人ID");
                        retAts.writeAfter();
                        return retAts;
                    } else {
                        map = JDBCHelper.execQuerySingle(conn, SELECTCLIENTID, new Object[]{p_req106.detail.discName, p_req106.reqHeader.bankCode});
                    }
                }


                //2.查询票据信息
                ReqB106BillDiscSubmitDetail detail = p_req106.detail;
                XmlTextReader billDetailReader = CQRT14(detail.actNum, detail.discBnkArea, detail.billCur, detail.billNo);
                if (billDetailReader == null) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("无法从银行查回票据信息");
                    retAts.writeAfter();
                    return retAts;
                }

                //3.发送报文请求到银行
                XmlTextWriter writerXml = new XmlTextWriter();
                ABC02Header header = new ABC02Header();
                header.CCTransCode = "CFRTA4";
                header.msgType = "5110";
                header.ReqDateTime = new Date();
                header.ReqSeqNo = getReqID();
                writeBillPoolCommonHead(writerXml, header);
                writerXml.writeStartElement("Dscnt");
                if (!StringHelper.isNullOrEmpty(p_req106.detail.discDate)) {
                    writerXml.writeElementString("AppDat", p_req106.detail.discDate, true);//贴现申请日期
                } else {
                    writerXml.writeElementString("AppDat", Format.Date10Format.format(new Date()), true);//贴现申请日期
                }
                if (!StringHelper.isNullOrEmpty(p_req106.detail.discType)) {
                    writerXml.writeElementString("TXTyp", "1".equals(p_req106.detail.discType) ? "RM00" : "RM01", true);//贴现种类 RM00买断式 RM01回购式
                } else {
                    writerXml.writeElementString("TXTyp", "", true);
                }
                writerXml.writeElementString("Rate", p_req106.detail.discRate, true);//年利率
                writerXml.writeElementString("TotalPayAmt", p_req106.detail.discAmt, true);//贴现实付总金额
                if (!StringHelper.isNullOrEmpty(p_req106.detail.payType)) {
                    writerXml.writeElementString("AccountFlg", "1".equals(p_req106.detail.payType) ? "SM00" : "SM01", true);//线上清算标记 SM00：线上清算SM01：线下清算
                } else {
                    writerXml.writeElementString("AccountFlg", "", true);
                }

                if (!StringHelper.isNullOrEmpty(p_req106.detail.transFlag)) {
                    writerXml.writeElementString("TransFlg", "1".equals(p_req106.detail.transFlag) ? "EM00" : "EM01", true);//不得转让标记 EM00可再转让 EM01不得转让
                } else {
                    writerXml.writeElementString("TransFlg", "", true);
                }
                writerXml.writeEndElement();//Dscnt

                writerXml.writeStartElement("DscntBk");
                writerXml.writeElementString("DbkProv", "", true);//贴入人开户账号省市代码
                writerXml.writeElementString("DbkAccNo", p_req106.detail.receAct, true);//贴入人开户账号
                writerXml.writeElementString("DbkNam", p_req106.detail.receName, true);//贴入人名称
                writerXml.writeElementString("DbkOpBnk", p_req106.detail.receBnkCode, true);//贴入人开户行行号
                writerXml.writeElementString("DbkOpBnkNam", p_req106.detail.receBnkName, true);//贴入人开户行名称
                writerXml.writeEndElement();//DscntBk

                writerXml.writeStartElement("AOAccnInf");
                writerXml.writeElementString("AoaBnk", p_req106.detail.actedBnkCode, true);//入账行行号
                writerXml.writeElementString("AoaBnkNam", p_req106.detail.actedBnkName, true);//入账行名称
                writerXml.writeEndElement();//AOAccnInf

                writerXml.writeStartElement("DscntPropsr");
                writerXml.writeElementString("DscNam", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToNam"), true);//名称
                writerXml.writeElementString("DscTyp", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToTyp"), true);//类别
                writerXml.writeElementString("DscOrgCode", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToOrgCode"), true);//组织机构代码
                writerXml.writeElementString("DscOpBnk", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnk"), true);//开户行行号
                writerXml.writeElementString("DscOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnkNam"), true);//开户行名称
                writerXml.writeElementString("DscConBnk", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToConBnk"), true);//承接行行号
                writerXml.writeElementString("DscConBnkNam", billDetailReader.getFirstText("/ap/Hermes/PayeeInfo/ToConBnkNam"), true);//承接行名称
                writerXml.writeEndElement();//DscntPropsr

                writerXml.writeElementString("BatchNo", "", true);//批次号
                writerXml.writeElementString("Note", p_req106.detail.memo);//备注
                writerXml.writeEndElement();//Hermes

                writerXml.writeStartElement("Cmp");
                writerXml.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                writerXml.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.discBnkArea));
                //农行开户行已103开头
                if (detail.actedBnkCode.startsWith("103")) {
                    writerXml.writeElementString("CrProv", "");
                    writerXml.writeElementString("CrAccNo", getFullAct(detail.actedAct, detail.actedBnkArea));
                } else {
                    writerXml.writeElementString("CrProv", "");
                    writerXml.writeElementString("CrAccNo", detail.actedAct);
                }
                writerXml.writeEndElement();//Cmp

                writerXml.writeStartElement("EBList");
                writerXml.writeStartElement("EBInfo");
                writerXml.writeElementString("ClientId", map.get("RESERVE2").toString(), true);//持票人客户ID
                writerXml.writeElementString("IdNb", p_req106.detail.billNo, true);//票据号
                writerXml.writeElementString("BillAmt", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillAmt"), true);//票据金额
                writerXml.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"), true);//票据类型
                writerXml.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"), true);//出票日期
                writerXml.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"), true);//到期日
                writerXml.writeElementString("ContNo", "", true);
                writerXml.writeElementString("InvoiceNo", "", true);
                writerXml.writeElementString("PayAmt", p_req106.detail.discAmt, true);//贴现实付金额
                writerXml.writeEndElement();//EBInfo
                writerXml.writeEndElement();//EBList

                writerXml.writeEndDocument();

                String[] tmpStrRet = sendToBank(writerXml.toXmlString());

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        RetAtsB106BillDiscSubmitDetail retAteDetail = new RetAtsB106BillDiscSubmitDetail();
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        retAts.writeRespCode("0");
                        retAts.writeRespInfo(StringHelper.joinNotEmpty(";", tmpRetInfo, tmpRetRxtInfo));
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            retAteDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        retAteDetail.respCode = "0";
                        retAteDetail.respInfo = tmpRetInfo;
                        retAteDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        retAteDetail.payInfoCode = retAteDetail.transState;
                        retAts.writeDetail(retAteDetail);
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpStrRet[1]);
                }
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            WriteBankLogLn("出现异常:" + e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeAfter();
        return retAts;
    }


    //原来的电票的贴现申请
    public RetAtsB106BillDiscSubmit elecBill_B106(ReqB106BillDiscSubmit query) throws Exception {
        RetAtsB106BillDiscSubmit Resp = new RetAtsB106BillDiscSubmit(query.reqHeader);
        Resp.writeBeforeDetail();

        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT56";
            header.msgType = "0110";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB106BillDiscSubmitDetail detail = query.detail;

            XmlTextReader billDetailReader = CQRT14(detail.actNum, detail.discBnkArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法从银行查回票据信息");
                Resp.writeAfter();
                return Resp;
            }

            XmlTextReader discountReader = CQRT12(detail, billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            if (discountReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法从银行获得贴现实付金额试算信息");
                Resp.writeAfter();
                return Resp;
            }

            //<Dscnt>
            //<AppDat>申请日期</AppDat>
            //<TXTyp>贴现种类</TXTyp>
            //<Rate>年利率</Rate>
            //<TotalPayAmt>贴现实付总金额</TotalPayAmt>
            //<AccountFlg>线上清算标记</AccountFlg>
            //<TransFlg>不得转让标记</TransFlg>
            //</Dscnt>
            writer.writeStartElement("Dscnt");
            writer.writeElementString("AppDat", Format.Date10Format.format(new Date()));
            writer.writeElementString("TXTyp", ELE_DISCOUNT_TYPE.getNotNull(detail.discType));
            BigDecimal discRate = new BigDecimal(detail.discRate);
            discRate = discRate.divide(new BigDecimal(100));
            writer.writeElementString("Rate", discRate.toString());
//            writer.writeElementString("Rate", formatDecimal2(detail.discRate));
            writer.writeElementString("TotalPayAmt", discountReader.getFirstText("/ap/Hermes/TotalPayAmt"));
            writer.writeElementString("AccountFlg", ELE_PAY_TYPE.getNotNull(detail.payType));
            writer.writeElementString("TransFlg", ELE_TRANS_FLAG.getNotNull(detail.transFlag));
            writer.writeEndElement();

            //<DscntBk>
            //<DBKProv>贴入人省市代码</DBKProv>
            //<DBKAccNo>贴入人账号</DBKAccNo>
            //<DBKNam>贴入人名称</DBKNam>
            //<DBKOpBnk>贴入人开户行行号</DBKOpBnk>
            //<DBKOpBnkNam>贴入人开户行名称</DBKOpBnkNam>
            //</DscntBk>
            writer.writeStartElement("DscntBk");
            writer.writeElementString("DBKProv", "");
            writer.writeElementString("DBKAccNo", detail.receAct);
            writer.writeElementString("DBKNam", detail.receName);
            writer.writeElementString("DBKOpBnk", detail.receBnkCode);
            writer.writeElementString("DBKOpBnkNam", detail.receBnkName);
            writer.writeEndElement();


            //<AOAccnInf>
            //<AOABnk>入账行行号</AOABnk>
            //<AOABnkNam>入账行名称</AOABnkNam>
            //</AOAccnInf>
            writer.writeStartElement("AOAccnInf");
            writer.writeElementString("AOABnk", detail.actedBnkCode);
            writer.writeElementString("AOABnkNam", CQRT06(detail.actedBnkCode));
            writer.writeEndElement();

            //<DscntPropsr>
            //<DscNam>贴现申请人名称</DscNam>
            //<DscTyp>贴现申请人类别</DscTyp>
            //<DscOrgCode>贴现申请人组织机构代码</DscOrgCode>
            //<DscOpBnkNam>贴现申请人开户行名称</DscOpBnkNam>
            //<DscConBnk>贴现申请人承接行行号</DscConBnk>
            //<DscConBnkNam>贴现申请人承接行名称</DscConBnkNam>
            //</DscntPropsr>
            XmlTextReader applyOrgReader = CQRT05(detail.actNum, detail.discBnkArea, detail.billCur);
            if (applyOrgReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法从银行查回申请人信息！");
                Resp.writeAfter();
                return Resp;
            }
            writer.writeStartElement("DscntPropsr");
            writer.writeElementString("DscNam", applyOrgReader.getFirstText("/ap/Hermes/Nam"));
            writer.writeElementString("DscTyp", applyOrgReader.getFirstText("/ap/Hermes/Typ"));
            writer.writeElementString("DscOrgCode", applyOrgReader.getFirstText("/ap/Hermes/OrgCode"));
            writer.writeElementString("DscOpBnk", applyOrgReader.getFirstText("/ap/Hermes/OpBnk"));
            writer.writeElementString("DscOpBnkNam", applyOrgReader.getFirstText("/ap/Hermes/OpBnkNam"));
            writer.writeElementString("DscConBnk", applyOrgReader.getFirstText("/ap/Hermes/ConBnk"));
            writer.writeElementString("DscConBnkNam", applyOrgReader.getFirstText("/ap/Hermes/ConBnkNam"));
            writer.writeEndElement();

            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            writer.writeElementString("Note", formatDecimal2(detail.memo));
            writer.writeElementString("BatchNo", query.detail.reqSeqID.length() > 10 ?
                    query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10) : query.detail.reqSeqID);
            writer.writeEndElement();
            //<EBList>
            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillAmt>票据金额</BillAmt>
            //<BillTyp>票据种类</BillTyp>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //<ContNo>交易合同编号</ContNo>
            //<InvoiceNo>发票号码</InvoiceNo>
            //<PayAmt>贴现实付金额</PayAmt>
            //</EBInfo>
            //</EBList>
            writer.writeStartElement("EBList");
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillAmt", formatDecimal2(detail.billAmt));
            writer.writeElementString("BillTyp", ELE_BILL_TYPE.getNotNull(detail.billType));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeElementString("ContNo", detail.contractNo);
            writer.writeElementString("InvoiceNo", detail.invoiceNo);
            writer.writeElementString("PayAmt", discountReader.getFirstText("/ap/EBList/EBInfo/PayAmt"));
            writer.writeEndElement();
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>贴现申请人账号</DbAccNo>
            //<DbProv>贴现申请人省市代码</DbProv>
            //<DbCur>贴现申请人货币码</DbCur>
            //<CrProv>入账账号省市代码</CrProv>
            //<CrAccNo>入账账号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
//            writer.writeElementString("CrProv", getConfiguredProvince(detail.actedAct));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.discBnkArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            //农行开户行已103开头
            if (detail.actedBnkCode.startsWith("103")) {
                writer.writeElementString("CrProv", "");
                writer.writeElementString("CrAccNo",
                        //省市+15位账号
//                        getAbcAccProv(detail.actedAct,detail.actedBnkArea)+getAbcAccNo(detail.actedAct));
                        getFullAct(detail.actedAct, detail.actedBnkArea));
            } else {
                writer.writeElementString("CrProv", "");
                writer.writeElementString("CrAccNo", detail.actedAct);
            }
            writer.writeEndElement();

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB106BillDiscSubmitDetail respDetail = new RetAtsB106BillDiscSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeRespCode(respDetail.respCode);
            Resp.writeRespInfo(respDetail.respInfo);
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    public XmlTextReader CQRT12(ReqB106BillDiscSubmitDetail detail, String endDate) throws Exception {
        ABC02Header header = new ABC02Header();
        XmlTextWriter writer = new XmlTextWriter();

        header.CCTransCode = "CQRT12";
        header.msgType = "0112";
        header.ReqDateTime = new Date();
        header.ReqSeqNo = reqHeader.transSeqID;
        writeEleCommonHead(writer, header);

        //<Dscnt>
        //<AppDat>申请日期</AppDat>
        //<Rate>年利率</Rate>
        //</Dscnt>
        writer.writeStartElement("Dscnt");
        writer.writeElementString("AppDat", formatDate10(reqHeader.transTime));
        BigDecimal discRate = new BigDecimal(detail.discRate);
        discRate = discRate.divide(new BigDecimal(100));
        writer.writeElementString("Rate", discRate.toString());
        writer.writeEndElement();

        //<Cmp>
        //<DbAccNo>账号</DbAccNo>
        //<DbProv>省市代码</DbProv>
        //<DbCur>货币码</DbCur>
        //</Cmp>
        writer.writeEndElement();
        writer.writeStartElement("Cmp");
//        writer.writeElementString("DbAccNo", detail.actNum);
//        writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//        writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
        writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
        writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.discBnkArea));
        String dbCur = convertCurToBank(detail.billCur);
        writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
        writer.writeEndElement();

        //<EBList>
        //<EBInfo>
        //<IdNb>票据号码</IdNb>
        //<BillAmt>票据金额</BillAmt>
        //<DueDat>到期日</DueDat>
        //</EBInfo>
        //</EBList>
        writer.writeStartElement("EBList");
        writer.writeStartElement("EBInfo");
        writer.writeElementString("IdNb", detail.billNo);
        writer.writeElementString("BillAmt", formatDecimal2(detail.billAmt));
        writer.writeElementString("DueDat", formatDate10(endDate));
        writer.writeEndElement();
        writer.writeEndElement();

        //发送银行
        writer.writeEndDocument();
        String[] tmpStrRet = sendToBank(writer.toXmlString());
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                    return tmpBkReader;
                }
            }
        }
        return null;
    }

    @Override
    public RetAtsB107BillPledSubmit D_B107_BillResp_Submit(ReqB107BillPledSubmit query) throws Exception {
        RetAtsB107BillPledSubmit Resp = new RetAtsB107BillPledSubmit(query.reqHeader);
        Resp.writeBeforeDetail();
        while (query.readRecord()) {

            XmlTextWriter writer = new XmlTextWriter();
//<ap>
//<Amt>金额</Amt>
//<Cmp>
//<DbAccNo>出质人账号</DbAccNo>
//<DbProv>出质人省市代码</DbProv>
//<DbCur>出质人货币码</DbCur>
//<CrAccNo>质权人帐号</CrAccNo>
//</Cmp>
//<Hermes>
//<Head>
//<MsgTyp>消息类型</MsgTyp>
//</Head>
//<Note>备注</Note>
//<BatchNo>批次号</BatchNo>
//</Hermes>
//</ap>

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT60";
            header.msgType = "0180";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);


            ReqB107BillPledSubmitDetail detail = query.detail;
            XmlTextReader billDetailReader = CQRT14(detail.actNum, detail.pledBnkArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法查回票据信息");
                Resp.writeAfter();
                return Resp;
            }

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<CollztnBk>
            //<CbNam>名称</CbNam>
            //<CbOpBnk>开户行行号</CbOpBnk>
            //<CbOpBnkNam>开户行名称</CbOpBnkNam>
            //</CollztnBk>
            writer.writeStartElement("CollztnBk");
            writer.writeElementString("CbNam", detail.receName);
            writer.writeElementString("CbOpBnk", detail.receBnkCode);
            writer.writeElementString("CbOpBnkNam", detail.receBnkName);
            writer.writeEndElement();


            //<CollztnPropsr>
            //<CpsrNam>名称</CpsrNam>
            //<CpsrTyp>类别</CpsrTyp>
            //<CpsrOpBnk>开户行行号</CpsrOpBnk>
            //<CpsrOpBnkNam>开户行名称</CpsrOpBnkNam>
            //<CpsrConBnk>承接行行号</CpsrConBnk>
            //<CpsrConBnkNam>承接行名称</CpsrConBnkNam>
            //</CollztnPropsr>
            writer.writeStartElement("CollztnPropsr");
            writer.writeElementString("CpsrNam", detail.pledName);
            writer.writeElementString("CpsrTyp", "RC01");
            writer.writeElementString("CpsrOpBnk", detail.pledBnkCode);
            writer.writeElementString("CpsrOpBnkNam", CQRT06(detail.pledBnkCode));
            writer.writeElementString("CpsrConBnk", "");
            writer.writeElementString("CpsrConBnkNam", "");
            writer.writeEndElement();

            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", "");
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>出质人账号</DbAccNo>
            //<DbProv>出质人省市代码</DbProv>
            //<DbCur>出质人货币码</DbCur>
            //<CrAccNo>质权人帐号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.pledBnkArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            if (query.detail.receBnkCode.startsWith("103") && !"0".equals(query.detail.receAct)) {
                writer.writeElementString("CrAccNo", getFullAct(query.detail.receAct, query.detail.receBnkArea));
            } else {
                writer.writeElementString("CrAccNo", query.detail.receAct);
            }
            writer.writeEndElement();

            //<Amt>金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB107BillPledSubmitDetail respDetail = new RetAtsB107BillPledSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    @Override
    public RetAtsB108BillPaySubmit D_B108_BillResp_Submit(ReqB108BillPaySubmit query) throws Exception {
        if (getBankConfig().getValueAsBool("isUseBillPoolTrans")) {
            //托管池的提示付款
            return billPool_B108(query);
        } else {
            //原来电票的提示付款
            return elecBill_B108(query);
        }
    }

    //托管池的提示付款
    public RetAtsB108BillPaySubmit billPool_B108(ReqB108BillPaySubmit p_req108) throws Exception {
        RetAtsB108BillPaySubmit retAts = new RetAtsB108BillPaySubmit(p_req108.reqHeader);
        retAts.writeBeforeDetail();
        try {
            while (p_req108.readRecord()) {
                //查询票据信息
                ReqB108BillPaySubmitDetail detail = p_req108.detail;
                XmlTextReader billDetailReader = CQRT34(detail.billNo);
                if (billDetailReader == null) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("无法从银行查回票据信息");
                    retAts.writeAfter();
                    return retAts;
                }

                //发送报文请求到银行
                XmlTextWriter writerXml = new XmlTextWriter();
                ABC02Header header = new ABC02Header();
                header.CCTransCode = "CFRT99";
                header.msgType = "5200";
                header.ReqDateTime = new Date();
                header.ReqSeqNo = getReqID();
                writeBillPoolCommonHead(writerXml, header);
                writerXml.writeStartElement("EBInfo");
                writerXml.writeElementString("ClientId", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/ClientId"), true);//持票单位ID
                writerXml.writeElementString("IdNb", p_req108.detail.billNo);//票据号码
                writerXml.writeElementString("BillTyp", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/BillTyp"), true);//票据类型
                writerXml.writeElementString("TransFlg", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/TransFlg"), true);//不可转让标识 EM00可再转让 EM01不得转让
                writerXml.writeElementString("IssDat", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/IssDat"), true);//出票日期
                writerXml.writeElementString("DueDat", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/DueDat"), true);//到期日
                writerXml.writeEndElement();//EBInfo

                writerXml.writeStartElement("Prsnttn");
                writerXml.writeElementString("Amt", billDetailReader.getFirstTextNotNull("/ap/Hermes/RemindInfo/Amt"), true);//提示付款金额
                if (!StringHelper.isNullOrEmpty(p_req108.detail.payType)) {
                    writerXml.writeElementString("OnlineFlg", "1".equals(p_req108.detail.payType) ? "SM00" : "SM01", true);//SM00：线上清算 SM01：线下清算
                    writerXml.writeElementString("OnlineFlgNam", "1".equals(p_req108.detail.payType) ? "线上清算" : "线下清算", true);//线上清算标记名称
                } else {
                    writerXml.writeElementString("OnlineFlg", "", true);
                    writerXml.writeElementString("OnlineFlgNam", "", true);
                }
                String isExpire = billDetailReader.getFirstTextNotNull("/ap/Hermes/RemindInfo/IsExpire");//是否已经逾期 0：不逾期，1：逾期
                writerXml.writeElementString("IsExpire", isExpire, true);
                if (!StringHelper.isNullOrEmpty(p_req108.detail.proPayType)) {
                    writerXml.writeElementString("UnExpire", "1".equals(p_req108.detail.proPayType) ? "DPF000" : "DPF001", true);//未到期付款
                } else {
                    writerXml.writeElementString("UnExpire", "0".equals(isExpire) ? "DPF000" : "DPF001", true);
                }

                writerXml.writeElementString("IsExpire", billDetailReader.getFirstTextNotNull("/ap/Hermes/RemindInfo/IsExpire"), true);//是否已经逾期
                writerXml.writeElementString("ExpireReason", p_req108.detail.overDueRea, true);//逾期原因
                writerXml.writeEndElement();//Prsnttn

                writerXml.writeStartElement("AccepterInfo");//收款人信息
                writerXml.writeElementString("AcepProv", "", true);//省市代码
                writerXml.writeElementString("AcepNam", billDetailReader.getFirstTextNotNull("/ap/Hermes/AccepterInfo/AcepNam"), true);//名称
                writerXml.writeElementString("AcepOpBnk", billDetailReader.getFirstTextNotNull("/ap/Hermes/AccepterInfo/AcepOpBnk"), true);//开户行行号
                writerXml.writeElementString("AcepOpBnkNam", billDetailReader.getFirstTextNotNull("/ap/Hermes/AccepterInfo/AcepOpBnkNam"), true);//开户行名称
                writerXml.writeEndElement();//AccepterInfo

                writerXml.writeStartElement("DrgtHldr");
                writerXml.writeElementString("DrgNam", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgNam"), true);//名称
                writerXml.writeElementString("DrgTyp", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgTyp"), true);//类别
                writerXml.writeElementString("DrgOrgCode", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgOrgCode"), true);//组织机构代码
                writerXml.writeElementString("DrgOpBnk", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgOpBnk"), true);//开户行行号
                writerXml.writeElementString("DrgOpBnkNam", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgOpBnkNam"), true);//开户行名称
                writerXml.writeElementString("DrgConBnk", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgConBnk"), true);//承接行行号
                writerXml.writeElementString("DrgConBnkNam", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgConBnkNam"), true);//承接行名称
                writerXml.writeEndElement();//DrgtHldr

                writerXml.writeElementString("BatchNo", "", true);//批次号
                writerXml.writeElementString("Note", p_req108.detail.memo, true);//备注

                writerXml.writeEndElement();//Hermes

                writerXml.writeStartElement("Cmp");
                writerXml.writeElementString("CrProv", "", true);//省市代码
                writerXml.writeElementString("CrAccNo", billDetailReader.getFirstTextNotNull("/ap/Hermes/AccepterInfo/AcepAccNo"), true);//接收人账号
                writerXml.writeElementString("DbProv", "", true);//省市代码
                writerXml.writeElementString("DbAccNo", billDetailReader.getFirstTextNotNull("/ap/Hermes/DrgtHldr/DrgAccNo"), true);//提示付款账号
                writerXml.writeEndElement();//Cmp

                writerXml.writeElementString("Amt", billDetailReader.getFirstTextNotNull("/ap/Hermes/EBInfo/BillAmt"));//票据金额
                writerXml.writeEndDocument();

                String[] tmpStrRet = sendToBank(writerXml.toXmlString());

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        RetAtsB108BillPaySubmitDetail retAteDetail = new RetAtsB108BillPaySubmitDetail();
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        retAts.writeRespCode("0");
                        retAts.writeRespInfo(StringHelper.joinNotEmpty(";", tmpRetInfo, tmpRetRxtInfo));
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            retAteDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        retAteDetail.respCode = "0";
                        retAteDetail.respInfo = tmpRetInfo;
                        retAteDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        retAteDetail.payInfoCode = retAteDetail.transState;
                        retAts.writeDetail(retAteDetail);
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpStrRet[1]);
                }

            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            WriteBankLogLn("出现异常:" + e.getMessage());
        }
        retAts.writeAfter();
        return retAts;
    }

    //原来电票的提示付款
    public RetAtsB108BillPaySubmit elecBill_B108(ReqB108BillPaySubmit query) throws Exception {
        RetAtsB108BillPaySubmit Resp = new RetAtsB108BillPaySubmit(query.reqHeader);
        Resp.writeBeforeDetail();
        while (query.readRecord()) {

            XmlTextWriter writer = new XmlTextWriter();

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT58";
            header.msgType = "0200";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

//<ap>
//<Amt>金额</Amt>
//<Cmp>
//<DbAccNo>提示付款人账号</DbAccNo>
//<DbProv>省市代码</DbProv>
//< DbCur >提示付款人货币码</ DbCur >
//<CrProv>承兑人省市代码</CrProv>
//<CrAccNo>承兑人帐号</CrAccNo>
//</Cmp>
//<Hermes>


            ReqB108BillPaySubmitDetail detail = query.detail;
            XmlTextReader billDetailReader = CQRT13(detail.actNum, detail.actArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法查回票据信息");
                Resp.writeAfter();
                return Resp;
            }
            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillAmt>票据金额</BillAmt>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillAmt", formatDecimal2(detail.billAmt));
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", billDetailReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<Prsnttn>
            //<Amt>提示付款金额</Amt>
            //<OnlineFlg>线上清算标记</OnlineFlg>
            //<OnlineFlgNam>线上清算标记名称</OnlineFlgNam>
            //<UnExpire>未到期付款</UnExpire>
            //<IsExpire> 是否已经逾期</IsExpire>
            //<ExpireReason>逾期原因</ExpireReason>
            //</Prsnttn>
            writer.writeStartElement("Prsnttn");
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));
            writer.writeElementString("OnlineFlg", ELE_PAY_TYPE.getNotNull(detail.payType));
            writer.writeElementString("OnlineFlgNam", convertPayTypeName(detail.payType));
            writer.writeElementString("UnExpire", ELE_EXPIRED_FLAG.getNotNull(detail.proPayType));
            writer.writeElementString("IsExpire", ELE_ISEXPIRED_FLAG.getNotNull(detail.proPayType));
            writer.writeElementString("ExpireReason", detail.overDueRea);
            writer.writeEndElement();

            //<AccepterInfo>
            //<AcepProv>省市代码</AcepProv>
            //<AcepNam>名称</AcepNam>
            //<AcepOpBnk>开户行行号</AcepOpBnk>
            //<AcepOpBnkNam>开户行名称</AcepOpBnkNam>
            //</AccepterInfo>
            writer.writeStartElement("AccepterInfo");
            writer.writeElementString("AcepProv", "");
            writer.writeElementString("AcepNam", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepNam"));
            writer.writeElementString("AcepOpBnk", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepOpBnk"));
            writer.writeElementString("AcepOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepOpBnkNam"));
            writer.writeEndElement();

            //<DrgtHldr>
            //<DrgNam>名称</DrgNam>
            //<DrgTyp>类别</DrgTyp>
            //<DrgOpBnk>开户行行号</DrgOpBnk>
            //<DrgOpBnkNam>开户行名称</DrgOpBnkNam>
            //<DrgConBnk>承接行行号</DrgConBnk>
            //<DrgConBnkNam>承接行名称</DrgConBnkNam>
            //</DrgtHldr>
            writer.writeStartElement("DrgtHldr");
            writer.writeElementString("DrgNam", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgNam"));
            writer.writeElementString("DrgTyp", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgTyp"));
            writer.writeElementString("DrgOpBnk", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgOpBnk"));
            writer.writeElementString("DrgOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgOpBnkNam"));
            writer.writeElementString("DrgConBnk", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgConBnk"));
            writer.writeElementString("DrgConBnkNam", billDetailReader.getFirstText("/ap/Hermes/DrgtHldr/DrgConBnkNam"));
            writer.writeEndElement();

            //<Note>备注</Note>
            writer.writeElementString("Note", detail.memo);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>提示付款人账号</DbAccNo>
            //<DbProv>省市代码</DbProv>
            //<DbCur>提示付款人货币码</DbCur>
            //<CrProv>承兑人省市代码</CrProv>
            //<CrAccNo>承兑人帐号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrProv", "");
            writer.writeElementString("CrAccNo", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepAccNo"));
            writer.writeEndElement();

            //<Amt>金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));


            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB108BillPaySubmitDetail respDetail = new RetAtsB108BillPaySubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    @Override
    public RetAtsB109BillGuarSubmit D_B109_BillResp_Submit(ReqB109BillGuarSubmit query) throws Exception {
        RetAtsB109BillGuarSubmit Resp = new RetAtsB109BillGuarSubmit(query.reqHeader);
        Resp.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT99";
            header.msgType = "5200";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB109BillGuarSubmitDetail detail = query.detail;

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", "");
            writer.writeElementString("IssDat", "");
            writer.writeElementString("DueDat", "");
            writer.writeEndElement();

            //<Guarntee>
            //<GteNam>保证人名称</GteNam>
            //<GteOpBnk>开户行行号</GteOpBnk>
            //<GteOpBnkNam>开户行名称</GteOpBnkNam>
            //</Guarntee>
            writer.writeStartElement("Guarntee");
            writer.writeElementString("GteNam", detail.guarName);
            writer.writeElementString("GteOpBnk", "");
            writer.writeElementString("GteOpBnkNam", "");
            writer.writeEndElement();

            //< Warntee >
            //<WteNam>名称</WteNam>
            //<WteTyp>类别</WteTyp>
            //<WteOpBnk>开户行行号</WteOpBnk>
            //<WteOpBnkNam>开户行名称</WteOpBnkNam>
            //<WteConBnk>承接行行号</WteConBnk>
            //<WteConBnkNam>承接行名称</WteConBnkNam>
            //</Warntee>
            writer.writeStartElement("Warntee");
            writer.writeElementString("WteNam", detail.receName);
            writer.writeElementString("WteTyp", "RC01");
            writer.writeElementString("WteOpBnk", detail.receBnkCode);
            writer.writeElementString("WteOpBnkNam", detail.receBnkName);
            writer.writeElementString("WteConBnk", "");
            writer.writeElementString("WteConBnkNam", "");
            writer.writeEndElement();

            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", detail.reqSeqID);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>被保证人账号</DbAccNo>
            //<DbProv>被保证人省市代码</DbProv>
            //<DbCur>被保证人货币码</DbCur>
            //<CrAccNo>保证人帐号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("CrAccNo", detail.receAct);
            writer.writeEndElement();

            //<Amt>金额</Amt>
            writer.writeElementString("Amt", detail.billAmt);

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB109BillGuarSubmitDetail respDetail = new RetAtsB109BillGuarSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    @Override
    public RetAtsB110BillRecoSubmit D_B110_BillResp_Submit(ReqB110BillRecoSubmit query) throws Exception {
        RetAtsB110BillRecoSubmit Resp = new RetAtsB110BillRecoSubmit(query.reqHeader);
        Resp.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();

            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT66";
            header.msgType = "0220";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB110BillRecoSubmitDetail detail = query.detail;

            if (StringUtils.isEmpty(detail.recourseCode)) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("追索理由不允许为空！");
                Resp.writeAfter();
                return Resp;
            }

            XmlTextReader billDetailReader = CQRM10(detail.actNum, detail.actArea, detail.billCur, detail.billNo);
            if (billDetailReader == null) {
                Resp.writeRespCode("-1");
                Resp.writeRespInfo("无法查回票据信息");
                Resp.writeAfter();
                return Resp;
            }
            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", billDetailReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<RcvgPrsnOfRcrs>
            //<RprNam>名称</RprNam>
            //<RprOrgCode>组织机构代码</RprOrgCode>
            //<RprOpBnk>开户行行号</RprOpBnk>
            //<RprOpBnkNam>开户行名称</RprOpBnkNam>
            //<RprConBnk>承接行行号</RprConBnk>
            //<RprConBnkNam>承接行名称</RprConBnkNam>
            //</RcvgPrsnOfRcrs>
            writer.writeStartElement("RcvgPrsnOfRcrs");
            writer.writeElementString("RprNam", detail.receName);
            writer.writeElementString("RprOrgCode", detail.receCode);
            writer.writeElementString("RprOpBnk", detail.receBnkCode);
            writer.writeElementString("RprOpBnkNam", detail.receBnkName);
            writer.writeElementString("RprConBnk", "");
            writer.writeElementString("RprConBnkNam", "");
            writer.writeEndElement();

            //<Rcrsr>
            // <RcrsrNam>追索人名称</RcrsrNam>
            //<RcrsrTyp>类别</RcrsrTyp>
            //<RcrsrOpBnk>开户行行号</RcrsrOpBnk>
            //<RcrsrOpBnkNam>开户行名称</RcrsrOpBnkNam>
            //<RcrsrConBnk>承接行行号</RcrsrConBnk>
            //<RcrsrConBnkNam>承接行名称</RcrsrConBnkNam>
            //</Rcrsr>
            writer.writeStartElement("Rcrsr");
            writer.writeElementString("RcrsrNam", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrNam"));
            writer.writeElementString("RcrsrTyp", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrTyp"));
            writer.writeElementString("RcrsrOpBnk", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrOpBnk"));
            writer.writeElementString("RcrsrOpBnkNam", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrOpBnkNam"));
            writer.writeElementString("RcrsrConBnk", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrConBnk"));
            writer.writeElementString("RcrsrConBnkNam", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrConBnkNam"));
            writer.writeEndElement();

            //<Rcrs>
            //<RcrsTyp>追索类型</RcrsTyp>
            //<RcrsAmt>追索金额</RcrsAmt>
            //<RcrsRsonCode>追索理由代码</RcrsRsonCode>
            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            //</Rcrs>
            writer.writeStartElement("Rcrs");
            writer.writeElementString("RcrsTyp", ELE_RECOURSE_TYPE.get(detail.recourseType));
            writer.writeElementString("RcrsAmt", formatDecimal2(detail.recourseAmt));
            writer.writeElementString("RcrsRsonCode", ELE_RECOURSE_REASON.get(detail.recourseCode));
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", "");
            writer.writeEndElement();

            writer.writeEndElement();
            //<Cmp>
            //<DbAccNo>追索人账号</DbAccNo>
            //<DbProv>追索人省市代码</DbProv>
            //<DbCur>追索人货币码</DbCur>
            //<CrAccNo>被追索人帐号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrAccNo", detail.receAct);
            writer.writeEndElement();

            //<Amt>票据金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB110BillRecoSubmitDetail respDetail = new RetAtsB110BillRecoSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            Resp.writeDetail(respDetail);
            break;
        }
        Resp.writeAfter();
        return Resp;
    }

    @Override
    public RetAtsB111BillAgreeSubmit D_B111_BillResp_Submit(ReqB111BillAgreeSubmit query) throws Exception {
        RetAtsB111BillAgreeSubmit result = new RetAtsB111BillAgreeSubmit(query.reqHeader);
        result.writeBeforeDetail();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();
            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT67";
            header.msgType = "0230";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB111BillAgreeSubmitDetail detail = query.detail;

            XmlTextReader billDetailReader = CQRT23(detail.busiNo, detail.actNum, detail.actNum, detail.billCur);

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"));
            writer.writeElementString("TransFlg", billDetailReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"));
            writer.writeElementString("IssDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/IssDat"));
            writer.writeElementString("DueDat", billDetailReader.getFirstText("/ap/Hermes/EBInfo/DueDat"));
            writer.writeEndElement();

            //<RcrsInfo>
            //	<Amt>同意清偿金额</Amt>
            //<RcrsTyp>追索类型</RcrsTyp>
            //</RcrsInfo>
            writer.writeStartElement("RcrsInfo");
            writer.writeElementString("Amt", formatDecimal2(detail.agreeAmt));
            writer.writeElementString("RcrsTyp", billDetailReader.getFirstText("/ap/Hermes/RcrsInfo/RcrsTyp"));
            writer.writeEndElement();

            //<Rcrs>
            //	<FrNam>名称</FrNam>
            //<FrTyp>类别</FrTyp>
            //<OpBnk>开户行行号</OpBnk>
            //<OpBnkNam>开户行名称</OpBnkNam>
            //<ConBnk>承接行行号</ConBnk>
            //</Rcrs>
            writer.writeStartElement("Rcrs");
            writer.writeElementString("FrNam", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepNam"));
            writer.writeElementString("FrTyp", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepTyp"));
            writer.writeElementString("OpBnk", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepOpBnk"));
            writer.writeElementString("OpBnkNam", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepOpBnkNam"));
            writer.writeElementString("ConBnk", billDetailReader.getFirstText("/ap/Hermes/AccepterInfo/AcepConBnk"));
            writer.writeEndElement();

            //<SpeInfo>
            //	<RecvBK>接收行行号</RecvBK>
            //</SpeInfo>
            writer.writeStartElement("SpeInfo");
            writer.writeElementString("RecvBK", billDetailReader.getFirstText("/ap/Hermes/Rcrsr/RcrsrOpBnk"));
            writer.writeEndElement();

            //<BefMes>
            //	<MesId>原报文标识号</MesId>
            //<MesTim>原报文时间</MesTim>
            //</BefMes>
            writer.writeStartElement("BefMes");
            writer.writeElementString("MesId", billDetailReader.getFirstText("/ap/Hermes/BefMes/MesId"));
            writer.writeElementString("MesTim", billDetailReader.getFirstText("/ap/Hermes/BefMes/MesTim"));
            writer.writeEndElement();
//            writer.writeEndElement();

            //<Note>备注</Note>
            //<BatchNo>批次号</BatchNo>
            writer.writeElementString("Note", detail.memo);
            writer.writeElementString("BatchNo", "");
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>同意清偿人账号</DbAccNo>
            //<DbProv>同意清偿人省市代码</DbProv>
            //<DbCur>同意清偿货币码</DbCur>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.agreeBnkArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeEndElement();

            //<Amt>金额</Amt>
            writer.writeElementString("Amt", billDetailReader.getFirstText("/ap/Hermes/EBInfo/BillAmt"));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB111BillAgreeSubmitDetail respDetail = new RetAtsB111BillAgreeSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = getReqSeqId(tmpBkReader.getFirstText("/ap/Hermes/Head/DealContent"));
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
//            result.writeRespCode(respDetail.respCode);
//            result.writeRespInfo(respDetail.respInfo);
            result.writeDetail(respDetail);
        }
        result.writeAfter();
        return result;
//        RetAtsB111BillAgreeSubmit ret = new RetAtsB111BillAgreeSubmit(reqHeader);
//        ret.writeRespCode("-1");
//        ret.writeRespInfo("该接口暂未开通，请联系技术人员");
//        return ret;
    }

    @Override
    public RetAtsB112BillCancSubmit D_B112_BillResp_Submit(ReqB112BillCancSubmit query) throws Exception {
        RetAtsB112BillCancSubmit result = new RetAtsB112BillCancSubmit(query.reqHeader);
        result.writeStart();
        while (query.readRecord()) {
            XmlTextWriter writer = new XmlTextWriter();
            //添加包头
            ABC02Header header = new ABC02Header();
            header.CCTransCode = "CFRT57";
            header.msgType = "0320";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = query.reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            ReqB112BillCancSubmitDetail detail = query.detail;

            //额外数据通过银行提供的接口查回
            Map<String, String> extraData = new HashMap<String, String>();

            RetAtsB001OperBillQryDetail billData = super.queryForAbleToRevokeBillDetail(detail.actNum, detail.billNo, detail.cancelType, detail.actArea, detail.billCur, extraData);
            if (billData == null) {
                result.writeRespCode("-1");
                result.writeRespInfo("无法从银行查到票据信息！");
                result.writeAfter();
                return result;
            }

            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //<BillTyp>票据种类</BillTyp>
            //<TransFlg>不得转让标记</TransFlg>
            //<IssDat>出票日期</IssDat>
            //<DueDat>到期日</DueDat>
            //</EBInfo>
            writer.writeStartElement("EBInfo");
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeElementString("BillTyp", ELE_BILL_TYPE.getNotNull(billData.billType));
            writer.writeElementString("TransFlg", ELE_TRANS_FLAG.getNotNull(billData.transFlag));
            writer.writeElementString("IssDat", formatDate10(billData.issDate));
            writer.writeElementString("DueDat", formatDate10(billData.dueDate));
            writer.writeEndElement();

            //<CPDInfo>
            //<CpdNam>被撤销人名称</CpdNam>
            //<CpdOpBnk>被撤销人开户行行号</CpdOpBnk>
            //<CpdOpBnkNam>被撤销人开户行名称</CpdOpBnkNam>
            //</CPDInfo>
            writer.writeStartElement("CPDInfo");
            writer.writeElementString("CpdNam", extraData.get("CpdNam"));
            writer.writeElementString("CpdOpBnk", extraData.get("CpdOpBnk"));
            writer.writeElementString("CpdOpBnkNam", extraData.get("CpdOpBnkNam"));
            writer.writeEndElement();

            XmlTextReader applyOrgReader = CQRT05(detail.actNum, detail.actArea, detail.billCur);
            if (applyOrgReader == null) {
                result.writeRespCode("-1");
                result.writeRespInfo("无法从银行查回申请人信息！");
                result.writeAfter();
                return result;
            }
            //<CxlPropsr>
            //<CpNam>撤回申请人名称</CpNam>
            //<CpTyp>撤回申请人类别</CpTyp>
            //<CpOrgCode>撤回申请人组织机构代码</CpOrgCode>
            //<CpOpBnk>撤回申请人开户行行号</CpOpBnk>
            //<CpOpBnkNam>撤回申请人开户行名称</CpOpBnkNam>
            //<CpConBnk>承接行行号</CpConBnk>
            //<CpConBnkNam>承接行名称</CpConBnkNam>
            //</CxlPropsr>
            writer.writeStartElement("CxlPropsr");
            writer.writeElementString("CpNam", applyOrgReader.getFirstText("/ap/Hermes/Nam"));
            writer.writeElementString("CpTyp", applyOrgReader.getFirstText("/ap/Hermes/Typ"));
            writer.writeElementString("CpOrgCode", applyOrgReader.getFirstText("/ap/Hermes/OrgCode"));
            writer.writeElementString("CpOpBnk", applyOrgReader.getFirstText("/ap/Hermes/OpBnk"));
            writer.writeElementString("CpOpBnkNam", applyOrgReader.getFirstText("/ap/Hermes/OpBnkNam"));
            writer.writeElementString("CpConBnk", applyOrgReader.getFirstText("/ap/Hermes/ConBnk"));
            writer.writeElementString("CpConBnkNam", applyOrgReader.getFirstText("/ap/Hermes/ConBnkNam"));
            writer.writeEndElement();

            //<SpeInfo>
            //<BusCode>业务编号</BusCode>
            //</SpeInfo>
            writer.writeStartElement("SpeInfo");
            writer.writeElementString("BusCode", detail.busiNo);
            writer.writeEndElement();
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>撤回申请人账号</DbAccNo>
            //<DbProv>撤回申请人省市代码</DbProv>
            //<DbCur>撤回申请人货币码</DbCur>
            //<CrProv>被撤销人省市代码</CrProv>
            //<CrAccNo>被撤销人账号</CrAccNo>
            //</Cmp>
            writer.writeStartElement("Cmp");
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeElementString("CrProv", extraData.get("CrProv"));
            writer.writeElementString("CrAccNo", extraData.get("CrAccNo"));
            writer.writeEndElement();

            //<Amt>票据金额</Amt>
            writer.writeElementString("Amt", formatDecimal2(detail.billAmt));

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            RetAtsB112BillCancSubmitDetail respDetail = new RetAtsB112BillCancSubmitDetail();
            respDetail.respCode = "-1";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    //当交易发送异常时，tmpRetRxtInfo不会为空
                    if (StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                        respDetail.respCode = "0";
                        respDetail.respInfo = tmpRetInfo;
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            respDetail.reqSeqID = detail.busiNo;
                        }
                        respDetail.transState = tmpBkReader.getFirstText("/ap/Channel/AbisRespCode");
                        respDetail.payInfoCode = respDetail.transState;
                    } else {
                        respDetail.respCode = "-1";
                        respDetail.respInfo = tmpRetInfo + "+" + tmpRetRxtInfo;
                    }
                } else {
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                respDetail.respCode = "-1";
                respDetail.respInfo = tmpStrRet[1];
            }
            result.writeRespCode(respDetail.respCode);
            result.writeRespInfo(respDetail.respInfo);
            result.writeDetail(respDetail);
        }
        result.writeAfter();
        return result;
    }

    @Override
    public RetAtsB113ProtocolSubmit D_B113_ProtocolResp_Submit(ReqB113ProtocolSubmit query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB119BillRelePledSubmit D_B119_BillResp_Submit(ReqB119BillRelePledSubmit query) throws Exception {
        return null;
    }

    public String getFullAct(String actNum, String area) throws Exception {
        return getAbcAccProv(actNum, area) + getAbcAccNo(actNum);
    }
}
